मेरे पास एक लंबा समय ListView
है जो उपयोगकर्ता पिछली स्क्रीन पर लौटने से पहले स्क्रॉल कर सकता है। जब उपयोगकर्ता इसे ListView
फिर से खोलता है , तो मैं चाहता हूं कि सूची उसी बिंदु पर स्क्रॉल की जाए जो पहले थी। इसे प्राप्त करने के बारे में कोई विचार?
मेरे पास एक लंबा समय ListView
है जो उपयोगकर्ता पिछली स्क्रीन पर लौटने से पहले स्क्रॉल कर सकता है। जब उपयोगकर्ता इसे ListView
फिर से खोलता है , तो मैं चाहता हूं कि सूची उसी बिंदु पर स्क्रॉल की जाए जो पहले थी। इसे प्राप्त करने के बारे में कोई विचार?
जवाबों:
इसे इस्तेमाल करे:
// save index and top position
int index = mList.getFirstVisiblePosition();
View v = mList.getChildAt(0);
int top = (v == null) ? 0 : (v.getTop() - mList.getPaddingTop());
// ...
// restore index and position
mList.setSelectionFromTop(index, top);
स्पष्टीकरण:
ListView.getFirstVisiblePosition()
शीर्ष दृश्यमान सूची आइटम लौटाता है। लेकिन इस आइटम को आंशिक रूप से स्क्रॉल किया जा सकता है, और यदि आप इस ऑफसेट को प्राप्त करने के लिए आवश्यक सूची की सटीक स्क्रॉल स्थिति को पुनर्स्थापित करना चाहते हैं। इसलिए शीर्ष सूची आइटम ListView.getChildAt(0)
के View
लिए वापस आता है , और फिर View.getTop() - mList.getPaddingTop()
ऊपर से इसकी सापेक्ष ऑफसेट लौटाता है ListView
। फिर, ListView
हम स्क्रॉल स्थिति को पुनर्स्थापित करने के लिए कॉल करते हैंListView.setSelectionFromTop()
उस आइटम के सूचकांक के साथ करते हैं जिसे हम चाहते हैं और एक ऑफसेट इसके शीर्ष किनारे से स्थिति को ऊपर करने के लिएListView
।
int index = mList.getFirstVisiblePosition();
और पुनर्स्थापित करने के लिए केवल एक लाइन mList.setSelectionFromTop(index, 0);
:। हालांकि महान जवाब (+1)! मैं इस समस्या का एक सुंदर समाधान ढूंढ रहा हूं।
Parcelable state;
@Override
public void onPause() {
// Save ListView state @ onPause
Log.d(TAG, "saving listview state");
state = listView.onSaveInstanceState();
super.onPause();
}
...
@Override
public void onViewCreated(final View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Set new items
listView.setAdapter(adapter);
...
// Restore previous state (including selected item index and scroll position)
if(state != null) {
Log.d(TAG, "trying to restore listview state");
listView.onRestoreInstanceState(state);
}
}
मैंने @ (Kirk Woll) द्वारा सुझाए गए समाधान को अपनाया, और यह मेरे लिए काम करता है। मैंने "संपर्क" ऐप के लिए एंड्रॉइड स्रोत कोड में भी देखा है, कि वे एक समान तकनीक का उपयोग करते हैं। मैं कुछ और विवरण जोड़ना चाहूंगा: शीर्ष पर मेरी ListActivity-व्युत्पन्न वर्ग:
private static final String LIST_STATE = "listState";
private Parcelable mListState = null;
फिर, कुछ विधि ओवरराइड होती है:
@Override
protected void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
mListState = state.getParcelable(LIST_STATE);
}
@Override
protected void onResume() {
super.onResume();
loadData();
if (mListState != null)
getListView().onRestoreInstanceState(mListState);
mListState = null;
}
@Override
protected void onSaveInstanceState(Bundle state) {
super.onSaveInstanceState(state);
mListState = getListView().onSaveInstanceState();
state.putParcelable(LIST_STATE, mListState);
}
बेशक "लोडडाटा" डीबी से डेटा प्राप्त करने और इसे सूची में डालने का मेरा कार्य है।
मेरे Froyo डिवाइस पर, यह तब काम करता है जब आप फ़ोन ओरिएंटेशन बदलते हैं, और जब आप किसी आइटम को संपादित करते हैं और सूची में वापस जाते हैं।
mListState = getListView().onSaveInstanceState().
मुख्य रूप से डिवाइस के रोटेशन पर कॉल करते समय सामग्री दृश्य नहीं बनाई जाती है ।
onRestoreInstanceState
कभी नहीं कहा जाता है :(
एक बहुत ही सरल तरीका:
/** Save the position **/
int currentPosition = listView.getFirstVisiblePosition();
//Here u should save the currentPosition anywhere
/** Restore the previus saved position **/
listView.setSelection(savedPosition);
विधि सेटिसलेशन सूची को आपूर्ति किए गए आइटम पर रीसेट करेगा। यदि टच मोड में नहीं है तो आइटम को वास्तव में चुना जाएगा यदि टच मोड में आइटम केवल स्क्रीन पर तैनात किया जाएगा।
अधिक जटिल दृष्टिकोण:
listView.setOnScrollListener(this);
//Implements the interface:
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
mCurrentX = view.getScrollX();
mCurrentY = view.getScrollY();
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
//Save anywere the x and the y
/** Restore: **/
listView.scrollTo(savedX, savedY);
मुझे इस बारे में कुछ दिलचस्प लगा।
मैंने सेट सेलेक्शन और स्क्रोलएक्सएक्सवाई की कोशिश की, लेकिन यह बिल्कुल भी काम नहीं किया, सूची उसी स्थिति में रही, कुछ परीक्षण और त्रुटि के बाद मुझे निम्नलिखित कोड मिला जो काम करता है
final ListView list = (ListView) findViewById(R.id.list);
list.post(new Runnable() {
@Override
public void run() {
list.setSelection(0);
}
});
यदि रननेबल को पोस्ट करने के बजाय आप रनऑन यूआईट्रेड की कोशिश करते हैं तो यह काम नहीं करता है (कम से कम कुछ उपकरणों पर)
यह किसी ऐसी चीज़ के लिए बहुत ही अजीब है जो सीधे आगे होनी चाहिए।
setSelectionFromTop()
काम नहीं करता है।
सावधान!! AbsListView में एक बग होता है, जो ListView.getFirstVanishPosition () 0 है, तो onSaveState () को सही ढंग से काम करने की अनुमति नहीं देता है।
इसलिए यदि आपके पास बड़ी छवियां हैं जो अधिकांश स्क्रीन को ऊपर ले जाती हैं, और आप दूसरी छवि पर स्क्रॉल करते हैं, लेकिन पहले से थोड़ी सी दिखाई दे रही है, तो स्क्रॉल स्थिति को सहेजा नहीं जाएगा ...
से AbsListView.java:1650 (टिप्पणी मेरा)
// this will be false when the firstPosition IS 0
if (haveChildren && mFirstPosition > 0) {
...
} else {
ss.viewTop = 0;
ss.firstId = INVALID_POSITION;
ss.position = 0;
}
लेकिन इस स्थिति में, नीचे दिए गए कोड में 'शीर्ष' एक नकारात्मक संख्या होगी जो अन्य मुद्दों का कारण बनता है जो राज्य को सही तरीके से बहाल करने से रोकते हैं। इसलिए जब 'शीर्ष' नकारात्मक हो, तो अगला बच्चा प्राप्त करें
// save index and top position
int index = getFirstVisiblePosition();
View v = getChildAt(0);
int top = (v == null) ? 0 : v.getTop();
if (top < 0 && getChildAt(1) != null) {
index++;
v = getChildAt(1);
top = v.getTop();
}
// parcel the index and top
// when restoring, unparcel index and top
listView.setSelectionFromTop(index, top);
private Parcelable state;
@Override
public void onPause() {
state = mAlbumListView.onSaveInstanceState();
super.onPause();
}
@Override
public void onResume() {
super.onResume();
if (getAdapter() != null) {
mAlbumListView.setAdapter(getAdapter());
if (state != null){
mAlbumListView.requestFocus();
mAlbumListView.onRestoreInstanceState(state);
}
}
}
बस काफी है
इस समस्या के समाधान की तलाश में कुछ के लिए, समस्या की जड़ वह जगह हो सकती है जहां आप अपनी सूची दृश्य एडेप्टर सेट कर रहे हैं। एडॉप्टर को सूची में सेट करने के बाद, यह स्क्रॉल स्थिति को रीसेट करता है। बस कुछ विचार करने के लिए। हमने सूची को संदर्भित करने के बाद एडेप्टर को मेरे ऑनक्रीट व्यू में स्थापित किया, और इसने मेरे लिए समस्या को हल कर दिया। =)
यह पोस्ट कर रहा हूँ क्योंकि मुझे आश्चर्य है कि किसी ने भी इसका उल्लेख नहीं किया था।
उपयोगकर्ता द्वारा बैक बटन पर क्लिक करने के बाद वह उसी स्थिति में सूची में वापस आ जाएगा, जब वह उससे बाहर गया था।
यह कोड लिस्टव्यू के मामले में बैक बटन के समान व्यवहार करने के लिए "अप" बटन को ओवरराइड कर देगा -> विवरण -> विवरण -> सूची पर वापस जाएं (और कोई अन्य विकल्प नहीं) यह स्क्रॉलपोस्ट और सामग्री को बनाए रखने का सबसे सरल कोड है सूची में।
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return(true);
}
return(super.onOptionsItemSelected(item)); }
सावधानी: यदि आप विवरण गतिविधि से किसी अन्य गतिविधि पर जा सकते हैं तो अप बटन आपको उस गतिविधि पर वापस लौटा देगा ताकि आपको काम करने के लिए बैकबटन इतिहास में हेरफेर करना पड़े।
बस android:saveEnabled="true"
सूची दृश्य xml घोषणा में पर्याप्त नहीं है?
सबसे अच्छा समाधान है:
// save index and top position
int index = mList.getFirstVisiblePosition();
View v = mList.getChildAt(0);
int top = (v == null) ? 0 : (v.getTop() - mList.getPaddingTop());
// ...
// restore index and position
mList.post(new Runnable() {
@Override
public void run() {
mList.setSelectionFromTop(index, top);
}
});
आप पोस्ट और तीन में कॉल करना होगा!
यदि आप पुनः लोड होने से पहले राज्य को सहेजते हैं और इसे पुनर्स्थापित करते हैं, तो आप पुनः लोड होने के बाद स्क्रॉल स्थिति बनाए रख सकते हैं। मेरे मामले में मैंने एक अतुल्यकालिक नेटवर्क अनुरोध किया और इसे पूरा करने के बाद कॉलबैक में सूची को पुनः लोड किया। यह वह जगह है जहां मैं राज्य को पुनर्स्थापित करता हूं। कोड नमूना कोटलिन है।
val state = myList.layoutManager.onSaveInstanceState()
getNewThings() { newThings: List<Thing> ->
myList.adapter.things = newThings
myList.layoutManager.onRestoreInstanceState(state)
}
यदि आप किसी गतिविधि पर होस्ट किए गए टुकड़ों का उपयोग कर रहे हैं, तो आप कुछ इस तरह कर सकते हैं:
public abstract class BaseFragment extends Fragment {
private boolean mSaveView = false;
private SoftReference<View> mViewReference;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (mSaveView) {
if (mViewReference != null) {
final View savedView = mViewReference.get();
if (savedView != null) {
if (savedView.getParent() != null) {
((ViewGroup) savedView.getParent()).removeView(savedView);
return savedView;
}
}
}
}
final View view = inflater.inflate(getFragmentResource(), container, false);
mViewReference = new SoftReference<View>(view);
return view;
}
protected void setSaveView(boolean value) {
mSaveView = value;
}
}
public class MyFragment extends BaseFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
setSaveView(true);
final View view = super.onCreateView(inflater, container, savedInstanceState);
ListView placesList = (ListView) view.findViewById(R.id.places_list);
if (placesList.getAdapter() == null) {
placesList.setAdapter(createAdapter());
}
}
}
यदि आप ListView
अपने आप को स्क्रॉल स्थिति को सहेज रहे हैं / पुनर्स्थापित कर रहे हैं तो आप अनिवार्य रूप से एंड्रॉइड फ्रेमवर्क में पहले से लागू कार्यक्षमता को दोहरा रहे हैं। ListView
पुनर्स्थापित ठीक पुस्तक की स्थिति अभी अच्छी तरह से अपने आप ही को छोड़कर एक चेतावनी के रूप @aaronvargas उल्लेख वहाँ एक बग में है AbsListView
कि पहली सूची आइटम के लिए ठीक पुस्तक स्थिति बहाल करने के लिए नहीं दूँगा। फिर भी स्क्रॉल स्थिति को पुनर्स्थापित करने का सबसे अच्छा तरीका इसे पुनर्स्थापित करना नहीं है। एंड्रॉइड फ्रेमवर्क आपके लिए इसे बेहतर करेगा। बस सुनिश्चित करें कि आप निम्नलिखित शर्तों को पूरा कर चुके हैं:
setSaveEnabled(false)
विधि को नहीं बुलाया है और सेट नहीं किया हैandroid:saveEnabled="false"
xml लेआउट फ़ाइल में सूची के लिए विशेषताExpandableListView
ओवरराइड long getCombinedChildId(long groupId, long childId)
विधि इतना है कि यह सकारात्मक लंबे संख्या (कक्षा में डिफ़ॉल्ट कार्यान्वयन रिटर्न BaseExpandableListAdapter
रिटर्न नकारात्मक संख्या)। यहाँ उदाहरण हैं:।
@Override
public long getChildId(int groupPosition, int childPosition) {
return 0L | groupPosition << 12 | childPosition;
}
@Override
public long getCombinedChildId(long groupId, long childId) {
return groupId << 32 | childId << 1 | 1;
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public long getCombinedGroupId(long groupId) {
return (groupId & 0x7FFFFFFF) << 32;
}
ListView
या ExpandableListView
एक टुकड़े में प्रयोग किया जाता है तो गतिविधि के मनोरंजन (उदाहरण के लिए स्क्रीन रोटेशन के बाद) पर टुकड़े को फिर से न बनाएँ। के साथ टुकड़ा प्राप्त करते हैंfindFragmentByTag(String tag)
विधि के ।ListView
एक है android:id
और यह अद्वितीय है।पहली सूची आइटम के साथ पूर्वोक्त चेतावनी से बचने के लिए आप अपने एडॉप्टर को उस तरह से शिल्प कर सकते हैं जिस तरह से यह ListView
स्थिति के लिए विशेष डमी शून्य पिक्सेल ऊँचाई दृश्य लौटाता है । यहां सरल उदाहरण प्रोजेक्ट शो है ListView
और ExpandableListView
उनके ठीक स्क्रॉल पदों को पुनर्स्थापित करना है जबकि उनके स्क्रॉल पदों को स्पष्ट रूप से सहेजा नहीं गया है / बहाल। ठीक स्क्रॉल स्थिति कुछ अन्य अनुप्रयोग, डबल स्क्रीन रोटेशन और परीक्षण अनुप्रयोग पर वापस स्विच करने के लिए अस्थायी स्विचिंग के साथ जटिल परिदृश्यों के लिए भी पूरी तरह से बहाल है। कृपया ध्यान दें, यदि आप स्पष्ट रूप से एप्लिकेशन से बाहर निकल रहे हैं (बैक बटन दबाकर) तो स्क्रॉल स्थिति को बचाया नहीं जाएगा (साथ ही अन्य सभी दृश्य उनके राज्य को नहीं बचाएंगे)।
https://github.com/voromto/RestoreScrollPosition/releases
ListActivity से प्राप्त एक गतिविधि के लिए जो LoaderManager.LoaderCallbacks को एक SimpleCursorAdapter का उपयोग करके लागू करता है, यह onReset () में स्थिति को पुनर्स्थापित करने के लिए काम नहीं करता था, क्योंकि गतिविधि को लगभग हमेशा पुनरारंभ किया गया था और विवरण देखने के बंद होने पर एडाप्टर को फिर से लोड किया गया था। चाल onLadFinished () में स्थिति को बहाल करने के लिए थी:
inListItemClick ():
// save the selected item position when an item was clicked
// to open the details
index = getListView().getFirstVisiblePosition();
View v = getListView().getChildAt(0);
top = (v == null) ? 0 : (v.getTop() - getListView().getPaddingTop());
inLoadFinished ():
// restore the selected item which was saved on item click
// when details are closed and list is shown again
getListView().setSelectionFromTop(index, top);
ऑनबीबैपड्रेस ():
// Show the top item at next start of the app
index = 0;
top = 0;
यहां दिए गए समाधानों में से कोई भी मेरे लिए काम नहीं करता था। मेरे मामले में, मेरे पास एक ListView
ऐसा है Fragment
जिसमें मैं एक जगह ले रहा हूं FragmentTransaction
, इसलिए Fragment
हर बार एक नया उदाहरण बनाया जाता है जब टुकड़ा दिखाया जाता है, जिसका अर्थ है कि ListView
राज्य को सदस्य के रूप में संग्रहीत नहीं किया जा सकता हैFragment
।
इसके बजाय, मैंने अपने कस्टम Application
वर्ग में राज्य का भंडारण किया । नीचे दिए गए कोड से आपको पता चल जाएगा कि यह कैसे काम करता है:
public class MyApplication extends Application {
public static HashMap<String, Parcelable> parcelableCache = new HashMap<>();
/* ... code omitted for brevity ... */
}
public class MyFragment extends Fragment{
private ListView mListView = null;
private MyAdapter mAdapter = null;
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mAdapter = new MyAdapter(getActivity(), null, 0);
mListView = ((ListView) view.findViewById(R.id.myListView));
Parcelable listViewState = MyApplication.parcelableCache.get("my_listview_state");
if( listViewState != null )
mListView.onRestoreInstanceState(listViewState);
}
@Override
public void onPause() {
MyApplication.parcelableCache.put("my_listview_state", mListView.onSaveInstanceState());
super.onPause();
}
/* ... code omitted for brevity ... */
}
मूल विचार यह है कि आप स्थिति को खंड के बाहर संग्रहीत करते हैं। यदि आपको अपनी एप्लिकेशन क्लास में एक स्थिर क्षेत्र होने का विचार पसंद नहीं है, तो मुझे लगता है कि आप इसे एक खंड इंटरफ़ेस लागू करके और अपनी गतिविधि में राज्य को संग्रहीत करके कर सकते हैं।
एक अन्य समाधान इसे स्टोर करना होगा SharedPreferences
, लेकिन यह थोड़ा अधिक जटिल हो जाता है, और आपको यह सुनिश्चित करने की आवश्यकता होगी कि आप इसे एप्लिकेशन लॉन्च पर स्पष्ट कर दें, जब तक कि आप नहीं चाहते कि राज्य को ऐप लॉन्च के बाद जारी रखा जाए।
इसके अलावा, "पहले आइटम दिखाई देने पर सहेजे नहीं गए स्क्रॉल स्थिति" से बचने के लिए, आप 0px
ऊंचाई के साथ एक डमी पहला आइटम प्रदर्शित कर सकते हैं । इसे getView()
अपने एडॉप्टर में ओवरराइड करके प्राप्त किया जा सकता है , जैसे:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if( position == 0 ) {
View zeroHeightView = new View(parent.getContext());
zeroHeightView.setLayoutParams(new ViewGroup.LayoutParams(0, 0));
return zeroHeightView;
}
else
return super.getView(position, convertView, parent);
}
मेरा जवाब फायरबेस और स्थिति 0 के लिए एक समाधान है
Parcelable state;
DatabaseReference everybody = db.getReference("Everybody Room List");
everybody.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
state = listView.onSaveInstanceState(); // Save
progressBar.setVisibility(View.GONE);
arrayList.clear();
for (DataSnapshot messageSnapshot : dataSnapshot.getChildren()) {
Messages messagesSpacecraft = messageSnapshot.getValue(Messages.class);
arrayList.add(messagesSpacecraft);
}
listView.setAdapter(convertView);
listView.onRestoreInstanceState(state); // Restore
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
और कन्वर्ट
स्थिति 0 कोई रिक्त आइटम जोड़ें जिसका आप उपयोग नहीं कर रहे हैं
public class Chat_ConvertView_List_Room extends BaseAdapter {
private ArrayList<Messages> spacecrafts;
private Context context;
@SuppressLint("CommitPrefEdits")
Chat_ConvertView_List_Room(Context context, ArrayList<Messages> spacecrafts) {
this.context = context;
this.spacecrafts = spacecrafts;
}
@Override
public int getCount() {
return spacecrafts.size();
}
@Override
public Object getItem(int position) {
return spacecrafts.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@SuppressLint({"SetTextI18n", "SimpleDateFormat"})
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.message_model_list_room, parent, false);
}
final Messages s = (Messages) this.getItem(position);
if (position == 0) {
convertView.getLayoutParams().height = 1; // 0 does not work
} else {
convertView.getLayoutParams().height = RelativeLayout.LayoutParams.WRAP_CONTENT;
}
return convertView;
}
}
मैंने उपयोगकर्ता को परेशान किए बिना यह काम अस्थायी रूप से देखा है, मुझे आशा है कि यह आपके लिए काम करता है
इस नीचे दिए गए कोड का उपयोग करें:
int index,top;
@Override
protected void onPause() {
super.onPause();
index = mList.getFirstVisiblePosition();
View v = challengeList.getChildAt(0);
top = (v == null) ? 0 : (v.getTop() - mList.getPaddingTop());
}
और जब भी आपका ताज़ा आपका डेटा इस कोड का उपयोग करें:
adapter.notifyDataSetChanged();
mList.setSelectionFromTop(index, top);
मैं FirebaseListAdapter का उपयोग कर रहा हूं और काम करने का कोई भी समाधान नहीं निकाल सका। मैंने ऐसा करना समाप्त कर दिया। मैं अनुमान लगा रहा हूं कि और अधिक सुंदर तरीके हैं लेकिन यह एक पूर्ण और काम करने वाला समाधान है।
OnCreate से पहले:
private int reset;
private int top;
private int index;
FirebaseListAdapter के अंदर:
@Override
public void onDataChanged() {
super.onDataChanged();
// Only do this on first change, when starting
// activity or coming back to it.
if(reset == 0) {
mListView.setSelectionFromTop(index, top);
reset++;
}
}
onStart:
@Override
protected void onStart() {
super.onStart();
if(adapter != null) {
adapter.startListening();
index = 0;
top = 0;
// Get position from SharedPrefs
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
top = sharedPref.getInt("TOP_POSITION", 0);
index = sharedPref.getInt("INDEX_POSITION", 0);
// Set reset to 0 to allow change to last position
reset = 0;
}
}
onStop:
@Override
protected void onStop() {
super.onStop();
if(adapter != null) {
adapter.stopListening();
// Set position
index = mListView.getFirstVisiblePosition();
View v = mListView.getChildAt(0);
top = (v == null) ? 0 : (v.getTop() - mListView.getPaddingTop());
// Save position to SharedPrefs
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
sharedPref.edit().putInt("TOP_POSITION" + "", top).apply();
sharedPref.edit().putInt("INDEX_POSITION" + "", index).apply();
}
}
चूंकि मुझे भी FirebaseRecyclerAdapter के लिए इसे हल करना था पोस्ट कर रहा हूं:
OnCreate से पहले:
private int reset;
private int top;
private int index;
FirebaseRecyclerAdapter के अंदर:
@Override
public void onDataChanged() {
// Only do this on first change, when starting
// activity or coming back to it.
if(reset == 0) {
linearLayoutManager.scrollToPositionWithOffset(index, top);
reset++;
}
}
onStart:
@Override
protected void onStart() {
super.onStart();
if(adapter != null) {
adapter.startListening();
index = 0;
top = 0;
// Get position from SharedPrefs
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
top = sharedPref.getInt("TOP_POSITION", 0);
index = sharedPref.getInt("INDEX_POSITION", 0);
// Set reset to 0 to allow change to last position
reset = 0;
}
}
onStop:
@Override
protected void onStop() {
super.onStop();
if(adapter != null) {
adapter.stopListening();
// Set position
index = linearLayoutManager.findFirstVisibleItemPosition();
View v = linearLayoutManager.getChildAt(0);
top = (v == null) ? 0 : (v.getTop() - linearLayoutManager.getPaddingTop());
// Save position to SharedPrefs
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
sharedPref.edit().putInt("TOP_POSITION" + "", top).apply();
sharedPref.edit().putInt("INDEX_POSITION" + "", index).apply();
}
}
रयान न्यूज़ोम के उत्कृष्ट उत्तर को स्पष्ट करने के लिए और इसे टुकड़ों के लिए समायोजित करने के लिए और सामान्य स्थिति के लिए जिसे हम "विवरण" के टुकड़े से "मास्टर" सूची में नेविगेट करना चाहते हैं और फिर "मास्टर" पर वापस जाएं।
private View root;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
if(root == null){
root = inflater.inflate(R.layout.myfragmentid,container,false);
InitializeView();
}
return root;
}
public void InitializeView()
{
ListView listView = (ListView)root.findViewById(R.id.listviewid);
BaseAdapter adapter = CreateAdapter();//Create your adapter here
listView.setAdpater(adapter);
//other initialization code
}
यहां "मैजिक" यह है कि जब हम विवरण खंड से वापस सूची दृश्य टुकड़े पर नेविगेट करते हैं, तो दृश्य को फिर से बनाया नहीं जाता है, हम सूची दृश्य के एडेप्टर को सेट नहीं करते हैं, इसलिए सब कुछ वैसा ही रहता है जैसा हमने छोड़ा था!