Skip to content
This repository was archived by the owner on Apr 9, 2021. It is now read-only.

Commit a46987b

Browse files
Control panel remember tab & position
1 parent 358a569 commit a46987b

File tree

10 files changed

+177
-97
lines changed

10 files changed

+177
-97
lines changed
0 Bytes
Binary file not shown.

app/src/main/java/org/indilib/i4j/iparcos/ConnectionFragment.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,8 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
8989
logAdapter.notifyDataSetChanged();
9090
clearLogsButton.animate().translationY(250);
9191
});
92-
9392
fabPosY = clearLogsButton.getScrollY();
94-
93+
if (logs.size() == 0) clearLogsButton.animate().setDuration(0).translationXBy(250);
9594
logsList.setOnScrollListener(new AbsListView.OnScrollListener() {
9695
@Override
9796
public void onScrollStateChanged(AbsListView view, int scrollState) {
@@ -103,7 +102,6 @@ public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCoun
103102
if (firstVisibleItem >= visibleItemCount) {
104103
clearLogsButton.animate().cancel();
105104
clearLogsButton.animate().translationYBy(250);
106-
107105
} else {
108106
clearLogsButton.animate().cancel();
109107
clearLogsButton.animate().translationY(fabPosY);
Lines changed: 91 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
package org.indilib.i4j.iparcos;
22

3+
import android.content.Context;
34
import android.os.Bundle;
45
import android.util.Log;
5-
import android.util.Pair;
66
import android.view.LayoutInflater;
7+
import android.view.Menu;
8+
import android.view.MenuInflater;
9+
import android.view.MenuItem;
710
import android.view.View;
811
import android.view.ViewGroup;
912
import android.widget.LinearLayout;
1013
import android.widget.TextView;
1114

1215
import androidx.annotation.NonNull;
16+
import androidx.appcompat.widget.SearchView;
1317
import androidx.fragment.app.Fragment;
1418
import androidx.viewpager2.adapter.FragmentStateAdapter;
1519
import androidx.viewpager2.widget.ViewPager2;
1620

21+
import com.google.android.material.tabs.TabLayout;
1722
import com.google.android.material.tabs.TabLayoutMediator;
1823

1924
import org.indilib.i4j.client.INDIDevice;
@@ -22,32 +27,43 @@
2227

2328
import java.util.ArrayList;
2429
import java.util.Date;
30+
import java.util.HashMap;
2531
import java.util.List;
2632

27-
public class ControlPanelFragment extends Fragment implements INDIServerConnectionListener {
33+
public class ControlPanelFragment extends Fragment
34+
implements INDIServerConnectionListener, SearchView.OnQueryTextListener {
2835

29-
private final ArrayList<Pair<INDIDevice, Fragment>> devicesAndFragments = new ArrayList<>();
30-
/**
31-
* Manages the connection with the INDI server.
32-
*
33-
* @see ConnectionManager
34-
*/
36+
private static final String KEY_VIEWPAGER_STATE = "DevicesViewPagerState";
37+
private static Bundle viewPagerBundle;
38+
private final ArrayList<INDIDevice> devices = new ArrayList<>();
39+
private final HashMap<Integer, Fragment> fragmentsMap = new HashMap<>();
3540
private ConnectionManager connectionManager;
36-
private DevicesFragmentAdapter devicesFragmentAdapter;
41+
private DevicesFragmentAdapter fragmentAdapter;
3742
private LinearLayout controlLayout;
3843
private TextView noDevicesText;
44+
private ViewPager2 viewPager;
45+
private TabLayout tabLayout;
46+
private Context context;
47+
48+
@Override
49+
public void onAttach(@NonNull Context context) {
50+
super.onAttach(context);
51+
this.context = context;
52+
}
3953

4054
@Override
4155
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
4256
View rootView = inflater.inflate(R.layout.fragment_control_panel, container, false);
4357
controlLayout = rootView.findViewById(R.id.indi_control_layout);
4458
noDevicesText = rootView.findViewById(R.id.no_devices_label);
45-
devicesAndFragments.clear();
46-
ViewPager2 viewPager = rootView.findViewById(R.id.indi_control_pager);
47-
viewPager.setAdapter(devicesFragmentAdapter = new DevicesFragmentAdapter(this));
48-
viewPager.setSaveEnabled(false);
49-
new TabLayoutMediator(rootView.findViewById(R.id.indi_control_tabs), viewPager,
50-
(tab, position) -> tab.setText(devicesAndFragments.get(position).first.getName())).attach();
59+
viewPager = rootView.findViewById(R.id.indi_control_pager);
60+
fragmentAdapter = new DevicesFragmentAdapter(this);
61+
viewPager.setAdapter(fragmentAdapter);
62+
viewPager.setOffscreenPageLimit(5);
63+
tabLayout = rootView.findViewById(R.id.indi_control_tabs);
64+
new TabLayoutMediator(tabLayout, viewPager,
65+
(tab, position) -> tab.setText(devices.get(position).getName())).attach();
66+
setHasOptionsMenu(true);
5167
return rootView;
5268
}
5369

@@ -65,28 +81,70 @@ public void onStart() {
6581
if (list.isEmpty()) {
6682
noDevices();
6783
} else {
68-
devicesAndFragments.clear();
6984
for (INDIDevice device : list) {
70-
newDevice(device);
85+
if (!devices.contains(device)) newDevice(device);
7186
}
72-
devicesFragmentAdapter.notifyDataSetChanged();
87+
viewPager.post(() -> {
88+
fragmentAdapter.notifyDataSetChanged();
89+
if (viewPagerBundle != null) {
90+
int position = viewPagerBundle.getInt(KEY_VIEWPAGER_STATE);
91+
viewPager.setCurrentItem(position, false);
92+
tabLayout.selectTab(tabLayout.getTabAt(position));
93+
}
94+
});
7395
devices();
7496
}
7597
}
7698
}
7799

100+
@Override
101+
public void onPause() {
102+
super.onPause();
103+
viewPagerBundle = new Bundle();
104+
viewPagerBundle.putInt(KEY_VIEWPAGER_STATE, viewPager.getCurrentItem());
105+
}
106+
107+
@Override
108+
public void onStop() {
109+
super.onStop();
110+
viewPager.setAdapter(null);
111+
}
112+
78113
@Override
79114
public void onDestroy() {
80115
super.onDestroy();
81116
noDevices();
82117
connectionManager.removeListener(this);
83118
}
84119

120+
@Override
121+
public void onCreateOptionsMenu(Menu menu, @NonNull MenuInflater inflater) {
122+
MenuItem item = menu.add(R.string.mount_goto);
123+
item.setIcon(R.drawable.search);
124+
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
125+
SearchView searchView = new SearchView(context);
126+
searchView.setOnQueryTextListener(this);
127+
item.setActionView(searchView);
128+
}
129+
130+
@Override
131+
public boolean onQueryTextChange(String newText) {
132+
Fragment fragment = fragmentsMap.get(viewPager.getCurrentItem());
133+
if (fragment instanceof DeviceControlFragment)
134+
((DeviceControlFragment) fragment).findPref(newText);
135+
return false;
136+
}
137+
138+
@Override
139+
public boolean onQueryTextSubmit(String query) {
140+
return false;
141+
}
142+
85143
private void noDevices() {
86-
devicesAndFragments.clear();
144+
devices.clear();
87145
noDevicesText.post(() -> noDevicesText.setVisibility(View.VISIBLE));
88146
controlLayout.post(() -> controlLayout.setVisibility(View.GONE));
89-
devicesFragmentAdapter.notifyDataSetChanged();
147+
viewPager.post(() -> fragmentAdapter.notifyDataSetChanged());
90148
}
91149

92150
private void devices() {
@@ -104,32 +162,23 @@ public void connectionLost(INDIServerConnection connection) {
104162
@Override
105163
public void newDevice(INDIServerConnection connection, INDIDevice device) {
106164
Log.i("ControlPanelFragment", "New device: " + device.getName());
107-
devicesFragmentAdapter.notifyItemInserted(newDevice(device));
165+
viewPager.post(() -> fragmentAdapter.notifyItemInserted(newDevice(device)));
108166
devices();
109167
}
110168

111169
private int newDevice(INDIDevice device) {
112-
PrefsFragment fragment = new PrefsFragment();
113-
fragment.setDevice(device);
114-
Pair<INDIDevice, Fragment> pair = new Pair<>(device, fragment);
115-
devicesAndFragments.add(pair);
116-
return devicesAndFragments.indexOf(pair);
170+
devices.add(device);
171+
return devices.indexOf(device);
117172
}
118173

119174
@Override
120175
public void removeDevice(INDIServerConnection connection, INDIDevice device) {
121176
Log.d("ControlPanelFragment", "Device removed: " + device.getName());
122-
for (int i = 0; i < devicesAndFragments.size(); i++) {
123-
Pair<INDIDevice, Fragment> pair = devicesAndFragments.get(i);
124-
if (pair.first == device) {
125-
devicesAndFragments.remove(pair);
126-
if (devicesAndFragments.isEmpty()) {
127-
noDevices();
128-
} else {
129-
devicesFragmentAdapter.notifyItemRemoved(i);
130-
}
131-
return;
132-
}
177+
int index = devices.indexOf(device);
178+
if (index != -1) {
179+
devices.remove(device);
180+
if (devices.isEmpty()) noDevices();
181+
viewPager.post(() -> fragmentAdapter.notifyItemRemoved(index));
133182
}
134183
}
135184

@@ -147,12 +196,15 @@ public DevicesFragmentAdapter(@NonNull Fragment fragment) {
147196
@NonNull
148197
@Override
149198
public Fragment createFragment(int position) {
150-
return devicesAndFragments.get(position).second;
199+
DeviceControlFragment fragment = new DeviceControlFragment();
200+
fragment.setDevice(devices.get(position));
201+
fragmentsMap.put(position, fragment);
202+
return fragment;
151203
}
152204

153205
@Override
154206
public int getItemCount() {
155-
return devicesAndFragments.size();
207+
return devices.size();
156208
}
157209
}
158210
}

app/src/main/java/org/indilib/i4j/iparcos/PrefsFragment.java renamed to app/src/main/java/org/indilib/i4j/iparcos/DeviceControlFragment.java

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77

88
import androidx.annotation.NonNull;
99
import androidx.annotation.Nullable;
10+
import androidx.preference.Preference;
1011
import androidx.preference.PreferenceCategory;
1112
import androidx.preference.PreferenceFragmentCompat;
1213
import androidx.preference.PreferenceScreen;
14+
import androidx.recyclerview.widget.RecyclerView;
1315

1416
import org.indilib.i4j.client.INDIDevice;
1517
import org.indilib.i4j.client.INDIDeviceListener;
@@ -19,12 +21,14 @@
1921
import java.util.HashMap;
2022
import java.util.List;
2123

22-
public class PrefsFragment extends PreferenceFragmentCompat implements INDIDeviceListener {
24+
public class DeviceControlFragment extends PreferenceFragmentCompat implements INDIDeviceListener {
2325

26+
private static final String KEY_RECYCLER_STATE = "PrefsRecyclerViewState";
27+
private static final HashMap<INDIDevice, Bundle> recyclerviewBundles = new HashMap<>();
28+
private final HashMap<INDIProperty<?>, PropPref<?>> preferencesMap = new HashMap<>();
29+
private final HashMap<String, PreferenceCategory> groups = new HashMap<>();
2430
private INDIDevice device = null;
2531
private PreferenceScreen prefScreen;
26-
private HashMap<INDIProperty<?>, PropPref<?>> map;
27-
private HashMap<String, PreferenceCategory> groups;
2832
private Context context;
2933

3034
@Override
@@ -40,12 +44,14 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
4044

4145
@Override
4246
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
43-
super.onViewCreated(view, savedInstanceState);
4447
prefScreen = getPreferenceScreen();
4548
if (device != null) {
49+
this.device.addINDIDeviceListener(this);
50+
preferencesMap.clear();
51+
groups.clear();
4652
for (String group : device.getGroupNames()) {
4753
List<INDIProperty<?>> props = device.getPropertiesOfGroup(group);
48-
if (props.size() > 0) {
54+
if (!props.isEmpty()) {
4955
PreferenceCategory prefGroup = new PreferenceCategory(context);
5056
prefGroup.setIconSpaceReserved(false);
5157
groups.put(group, prefGroup);
@@ -55,31 +61,58 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
5561
PropPref<?> pref = PropPref.create(context, prop);
5662
if (pref != null) {
5763
pref.setIconSpaceReserved(false);
58-
map.put(prop, pref);
64+
preferencesMap.put(prop, pref);
5965
prefGroup.addPreference(pref);
6066
}
6167
}
6268
}
6369
}
6470
}
71+
super.onViewCreated(view, savedInstanceState);
72+
if (device != null) {
73+
Bundle recyclerviewBundle = recyclerviewBundles.get(device);
74+
if (recyclerviewBundle != null) {
75+
RecyclerView.LayoutManager layoutManager = getListView().getLayoutManager();
76+
if (layoutManager != null)
77+
layoutManager.onRestoreInstanceState(recyclerviewBundle.getParcelable(KEY_RECYCLER_STATE));
78+
}
79+
}
6580
}
6681

67-
public void setDevice(INDIDevice device) {
68-
this.device = device;
69-
this.device.addINDIDeviceListener(this);
70-
map = new HashMap<>();
71-
groups = new HashMap<>();
82+
@Override
83+
public void onPause() {
84+
super.onPause();
85+
if (device != null) {
86+
Bundle recyclerviewBundle = new Bundle();
87+
RecyclerView.LayoutManager layoutManager = getListView().getLayoutManager();
88+
if (layoutManager != null)
89+
recyclerviewBundle.putParcelable(KEY_RECYCLER_STATE, layoutManager.onSaveInstanceState());
90+
recyclerviewBundles.put(device, recyclerviewBundle);
91+
}
7292
}
7393

7494
@Override
75-
public void finalize() throws Throwable {
76-
super.finalize();
95+
public void onDestroyView() {
96+
super.onDestroyView();
7797
device.removeINDIDeviceListener(this);
7898
}
7999

80-
@Override
81-
public void messageChanged(INDIDevice device) {
100+
public void setDevice(INDIDevice device) {
101+
this.device = device;
102+
}
82103

104+
public void findPref(String newText) {
105+
for (int i = 0; i < prefScreen.getPreferenceCount(); i++) {
106+
PreferenceCategory group = ((PreferenceCategory) prefScreen.getPreference(i));
107+
for (int j = 0; j < group.getPreferenceCount(); j++) {
108+
Preference preference = group.getPreference(j);
109+
if (preference.getTitle().toString().toLowerCase().startsWith(newText.toLowerCase())) {
110+
RecyclerView.LayoutManager layoutManager = getListView().getLayoutManager();
111+
if (layoutManager != null) layoutManager.scrollToPosition(j);
112+
return;
113+
}
114+
}
115+
}
83116
}
84117

85118
@Override
@@ -97,15 +130,15 @@ public void newProperty(INDIDevice device, final INDIProperty<?> property) {
97130
PropPref<?> pref = PropPref.create(context, property);
98131
if (pref != null) {
99132
pref.setIconSpaceReserved(false);
100-
map.put(property, pref);
133+
preferencesMap.put(property, pref);
101134
prefGroup.addPreference(pref);
102135
}
103136
});
104137
}
105138

106139
@Override
107140
public void removeProperty(INDIDevice device, INDIProperty<?> property) {
108-
PropPref<?> pref = map.get(property);
141+
PropPref<?> pref = preferencesMap.get(property);
109142
if (pref != null) {
110143
String group = property.getGroup();
111144
PreferenceCategory prefGroup = groups.get(group);
@@ -116,7 +149,12 @@ public void removeProperty(INDIDevice device, INDIProperty<?> property) {
116149
groups.remove(group);
117150
}
118151
}
119-
map.remove(property);
152+
preferencesMap.remove(property);
120153
}
121154
}
155+
156+
@Override
157+
public void messageChanged(INDIDevice device) {
158+
159+
}
122160
}

0 commit comments

Comments
 (0)