الحفاظ على موضع التمرير عند إضافة الى ListView مع عكس التي لا نهاية لها-التمرير

StackOverflow https://stackoverflow.com//questions/22051556

سؤال

أنا بناء على دردشة مثل الروبوت التطبيق, مماثلة إلى Hangouts.لهذا الغرض أنا باستخدام العمودي ListView مع stackFromBottom=true و transcriptMode="normal".

يتم فرز القائمة من الرسائل القديمة (أعلى) إلى الأصغر رسائل (الجزء السفلي).في الحالة الطبيعية ، ListView يتم تمريره إلى أسفل ، تظهر أصغر رسالة.

ListView يستخدم العكسي التي لا نهاية لها-انتقل محول لتحميل المزيد من (كبار السن) الرسائل بمجرد تمرير المستخدم إلى الجزء العلوي من القائمة.بمجرد الرسائل القديمة يتم تحميلها ، يتم إضافتها إلى الجزء العلوي من القائمة.

السلوك المطلوب هو أن ListView يحافظ انتقل إلى أسفل القائمة ، عند كبار السن اضافة رسائل إلى أعلى من ذلك.هذا هو عندما الرسائل القديمة إضافة إلى الأعلى ، انتقل-بعد أن تظهر نفس الرسائل التي كانت تظهر قبل إضافة الرسائل القديمة.

للأسف هذا لا يعمل.بدلا من الحفاظ على التمرير إلى أسفل ، ListView يحافظ على التمرير الموقف إلى أعلى القائمة.هذا هو بعد إضافة الرسائل القديمة إلى القائمة, القائمة يظهر الأعلى (أنا.هـ أقدم) رسائل.

هل هناك طريقة سهلة لمعرفة ListView للحفاظ على التمرير إلى الأسفل بدلا من الأعلى, عند إضافة عناصر جديدة إلى أعلى من ذلك ؟

التحديث

لأغراض العرض التوضيحي ، يجب التقليل من استخدام القضية ورمز قدر الإمكان.يقوم المثال التالي بإنشاء سلسلة بسيطة مجموعة قائمة.النقر على هذا البند سيتم إضافة بند آخر في الجزء العلوي من القائمة.النقر طويلة على البند سيتم إضافة بند آخر في الجزء السفلي من القائمة.

كل شيء يعمل بشكل جيد عند إضافة العناصر في الجزء السفلي من القائمة (طويل فوق).عند إضافة العناصر في الجزء العلوي من قائمة (نقرة بسيطة) ، ثم هناك 3 حالات:

  • إذا كانت تمريره إلى أسفل ، ثم كل شيء يعمل بشكل جيد.بعد إضافة هذا البند إلى أعلى القائمة لا تزال تمريره إلى أسفل.
  • إذا لم تكن القائمة تمريره إلى أسفل (أو أعلى) ، ثم قائمة الحفاظ على التمرير-y الموقف (من أعلى).هذا يجعل قائمة تظهر على "القفز" عنصر واحد حتى.أود قائمة لا "تقفز" في هذه الحالة،.ه وأود أن الحفاظ على التمرير-y الموقف من أسفل.
  • إذا كانت القائمة تمريره إلى أعلى ، ثم يحدث نفسه كما في حالة 2.المفضل السلوك هو نفس الحالة 2.

(آخر 2 الحالات هي في الواقع نفس الشيء.صنفتهم لأن المشكلة يمكن أن يكون أفضل موضح في الحالة 2.)

رمز

public class MyListActivity extends Activity {
  int topIndex = 1;

  int bottomIndex = 20;

  protected final void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.my_list_activity);

    final ListView list = (ListView) findViewById(R.id.list);
    list.setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL);
    list.setStackFromBottom(true);

    final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1);
    for (int i = topIndex; i <= bottomIndex; i++) {
      adapter.add(Integer.toString(i));
    }
    list.setAdapter(adapter);

    list.setOnItemClickListener(new OnItemClickListener() {
      @Override
      public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
        adapter.insert(Integer.toString(--topIndex), 0);
      }
    });

    list.setOnItemLongClickListener(new OnItemLongClickListener() {
      @Override
      public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
        adapter.add(Integer.toString(++bottomIndex));
        return true;
      }
    });
  }
}
هل كانت مفيدة؟

المحلول

لقد اكتشفت هذا.أينما يتم الحصول على البيانات الجديدة أدعو التالية قبل تغيير البيانات في محول:

int firstVisibleItem = list.getFirstVisiblePosition();
int oldCount = adapter.getCount();
View view = list.getChildAt(0);
int pos = (view == null ? 0 :  view.getBottom());

ثم أتصل على:

adapter.setData(data);

list.setSelectionFromTop(firstVisibleItem + adapter.getCount() - oldCount + 1, pos);

نصائح أخرى

أولا الحصول على firstVisiblePosition (أو آخر منذ رأسا على عقب.يو حصلت في محاولة التحقق من ذلك بنفسك) ومن ثم الحصول على أعلى العرض الذي يضاف إلى قائمة ثم باستخدام setSe;ectionFromTop (طريقة) ، يمكنك انتقل إلى الموقع المطلوب.

كود:

int index = mList.getFirstVisiblePosition();
View v = mList.getChildAt(0); //or upside down (list.size - 1)
int top = (v == null) ? 0 : v.getTop(); //returns the top of the view its Y co-ordinates. [Doc][1]
mList.setSelectionFromTop(index, top);

المصدر.

تحرير الحساب للحصول على معلومات إضافية:

أعتقد أنني قد وجدت المشكلة.أنا تكرارها الخاص بك وصفت حالات الاستخدام باستخدام قائمة بذاتها كما عرض فقط في XML:

<ListView
    android:id="@+id/list"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
</ListView>

لقد أصلحت المشكلة لمتابعة المطلوب حالات الاستخدام من قبل التعشيش تخطيط في تخطيط الوالدين:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ListView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </ListView>

</FrameLayout>

بعد إدراج سجل في محول يمكنك محاولة استخدام

   yourListView.setSelection(yourAdapter.getCount() - 1);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top