Как добавить заголовок в listView, который находится внутри SwipeRefreshLayout?

Фон

Я заметил проблему (ссылка здесь<) /a>) при добавлении представления заголовка внутри ListView, если ListView находится внутри SwipeRefreshLayout.

Эта проблема

Проблема в том, что если вид заголовка частично виден и вы прокручиваете вверх, вы увидите круговой вид SwipeRefreshLayout.

Вы можете проверить ссылку выше, чтобы посмотреть видео о том, о чем я говорю.

Образец кода

Вот как воспроизвести эту проблему (вы можете проверить ссылку выше, если вы не хотите копировать и вставлять):

MainActivity.java

public class MainActivity extends ActionBarActivity
  {
  @Override
  protected void onCreate(final Bundle savedInstanceState)
    {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final ListView listView=(ListView)findViewById(android.R.id.list);
    final TextView tv=new TextView(this);
    tv.setText("a very large header view");
    tv.setTextSize(70);
    listView.addHeaderView(tv);
    final SwipeRefreshLayout swipeRefreshLayout=(SwipeRefreshLayout)findViewById(R.id.swipeToRefreshLayout);
    swipeRefreshLayout.setOnRefreshListener(new OnRefreshListener()
      {
        @Override
        public void onRefresh()
          {
          new Handler().postDelayed(new Runnable()
            {
              @Override
              public void run()
                {
                swipeRefreshLayout.setRefreshing(false);
                }
            },1000);
          }
      });
    final ArrayList<String> arrayList=new ArrayList<String>();
    for(int i=0;i<1000;++i)
      arrayList.add(Integer.toString(i));
    listView.setAdapter(new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,arrayList));
    }
  }

res/layout/activity_main.xml

<android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/swipeToRefreshLayout"
    android:layout_width="match_parent" xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_height="match_parent" >

    <ListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:cacheColorHint="@android:color/transparent"
        android:fastScrollEnabled="true"
        android:footerDividersEnabled="true"
        android:headerDividersEnabled="true"
        android:paddingEnd="4dp"
        android:paddingLeft="4dp"
        android:paddingRight="4dp"
        android:paddingStart="4dp"
        android:scrollingCache="false"
        android:smoothScrollbar="false"
        android:textFilterEnabled="true"/>

</android.support.v4.widget.SwipeRefreshLayout>

Вопрос

Есть ли способ решить эту проблему?

Я думаю, что я мог бы использовать несколько типов для listView , но может быть есть другое решение, более элегантное, простое или лучше каким-либо другим образом?


person android developer    schedule 20.11.2014    source источник
comment
Да, но тогда он находится над ListView, что не позволяет просматривать круговой вид SwipeRefreshLayout, которому он принадлежит. Кроме того, TextView не будет прокручиваться и станет частью listView таким образом.   -  person android developer    schedule 20.11.2014


Ответы (2)


Очень похоже на проблему Android 78375. Попробуйте переопределить SwipeRefreshLayout#canChildScrollUp

@Override
public boolean canChildScrollUp() {
    View target = getChildAt(0);
    if (target instanceof AbsListView) {
        final AbsListView absListView = (AbsListView) target;
        return absListView.getChildCount() > 0
                && (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0)
                .getTop() < absListView.getPaddingTop());
    } else {
        return target.getScrollY() > 0;
    }
}
person ls.illarionov    schedule 25.01.2015
comment
Спасибо. Теперь будет отмечать это как правильный ответ, пока Google не исправит эту проблему. Скажем, если вы хорошо разбираетесь в RecyclerView, не могли бы вы проверить это: stackoverflow.com/questions/27798212/ ? - person android developer; 26.01.2015

РЕДАКТИРОВАТЬ: кажется, это происходит, даже если я использую элементы с несколькими типами для ListView. Позже я обнаружил, что это всегда происходит для первого элемента в listView.

Если первый элемент достаточно большой, его будет легко воспроизвести.

Итак, на данный момент есть простой обходной путь:

Прежде чем каким-либо образом использовать представление списка, сначала добавьте пустое представление в качестве представления заголовка и никогда не удаляйте его:

listView.addHeaderView(new View(this));

Таким образом, поскольку вид практически невидим, ошибка не будет показана пользователю.

Это всего лишь обходной путь, но я думаю, что лучше всего решить эту проблему.

person android developer    schedule 20.11.2014