Android Expandable-Header RecyclerView滚动滞后

时间:2019-01-25 13:35:57

标签: android android-recyclerview expandablelistadapter

我的Expandable RecyclerView涉及滚动滞后问题。 应该注意的是,滞后是在滚动标题时发生的,而不是在滚动子项时发生的。

行布局(recycler_row_expandable.xml):

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="@color/blonde">

    <ImageView
        android:id="@+id/categoryPicture"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="5dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />

    <TextView
        android:id="@+id/headerText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="23sp"
        android:textStyle="bold"
        android:textColor="@color/black"
        android:layout_marginStart="5dp"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="10dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@id/categoryPicture"
        app:layout_constraintTop_toTopOf="parent"
        />

    <ImageView
        android:id="@+id/headerPicture"
        android:src="@drawable/logo_arrow_expandable"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="@dimen/margin_standard"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />

</android.support.constraint.ConstraintLayout>

适配器:

public class ActivityRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements
        ActivityRecyclerHeaderViewHolder.HeaderViewHolderCallback, ActivityRecyclerChildViewHolder.ChildViewHolderCallback {
    private Context context;
    private final int ACTIVITY_TYPE = 1;
    private final int HEADER_TYPE = 2;
    private List<String> activityHeaderList;
    private List<String> activityChildList;
    private Map<String, Integer> numberOfChildrenPerParentNameMap;
    private SparseArray<ActivityRecyclerViewType> viewTypes;
    private SparseIntArray headerExpandTracker;

    public ActivityRecyclerAdapter(Context context, List<String> activityHeaderList, List<String> activityTypeList, Map<String, Integer> numberOfChildrenPerParent) {
        this.context = context;
        this.activityHeaderList = activityHeaderList;
        this.activityChildList = activityTypeList;
        this.numberOfChildrenPerParentNameMap = numberOfChildrenPerParent;
        headerExpandTracker = new SparseIntArray(activityHeaderList.size());
        viewTypes = new SparseArray<>(activityHeaderList.size() + activityTypeList.size());
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view;
        switch (viewType) {
            case ACTIVITY_TYPE:
                view = LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.recycler_row_child, parent, false);
                return new ActivityRecyclerChildViewHolder(view, this);
            case HEADER_TYPE:
                view = LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.recycler_row_expandable, parent, false);
                return new ActivityRecyclerHeaderViewHolder(view, this);
            default:
                view = LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.recycler_row_child, parent, false);
                return new ActivityRecyclerChildViewHolder(view, this);
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        int itemViewType = getItemViewType(position);
        ActivityRecyclerViewType viewType = viewTypes.get(position);
        if (itemViewType == ACTIVITY_TYPE) {
            bindChildViewHolder(holder, viewType);
        } else {
            bindHeaderViewHolder(holder, position, viewType);
        }
    }

    private void bindHeaderViewHolder(RecyclerView.ViewHolder holder, int position, ActivityRecyclerViewType viewType) {
        int dataIndex = viewType.getDataIndex();
        ActivityRecyclerHeaderViewHolder headerViewHolder = (ActivityRecyclerHeaderViewHolder) holder;
        headerViewHolder.sectionTitle.setText(activityHeaderList.get(dataIndex));
        if (position < ChooseCategoryActivity.allImagesNames.length) {
            headerViewHolder.categoryImage.setImageDrawable(context.getResources().getDrawable(ChooseCategoryActivity.allImagesNames[position]));
        }
        if (isExpanded(position)) {
            headerViewHolder.sectionTitle
                    .setCompoundDrawablesWithIntrinsicBounds(null, null, null/*headerViewHolder.arrowUp*/, null);
        } else {
            headerViewHolder.sectionTitle
                    .setCompoundDrawablesWithIntrinsicBounds(null, null, null /*headerViewHolder.arrowDown*/, null);
        }
    }

    private void bindChildViewHolder(RecyclerView.ViewHolder holder, ActivityRecyclerViewType viewType) {
        int dataIndex = viewType.getDataIndex();
        ((ActivityRecyclerChildViewHolder) holder).name.setText(activityChildList.get(dataIndex));
    }

    @Override
    public int getItemCount() {
        int count = 0;
        if (activityChildList != null && activityHeaderList != null && headerExpandTracker != null) {
            viewTypes.clear();
            int collapsedCount = 0;
            for (int i = 0; i < activityHeaderList.size(); i++) {
                viewTypes.put(count, new ActivityRecyclerViewType(i, HEADER_TYPE));
                count += 1;
                String userType = activityHeaderList.get(i);
                int childCount = numberOfChildrenPerParentNameMap.get(userType);
                if (headerExpandTracker.get(i) != 0) {
                    // Expanded State
                    for (int j = 0; j < childCount; j++) {
                        viewTypes.put(count, new ActivityRecyclerViewType(count - (i + 1) + collapsedCount, ACTIVITY_TYPE));
                        count += 1;
                    }
                } else {
                    // Collapsed
                    collapsedCount += childCount;
                }
            }
        }
        return count;
    }

    @Override
    public int getItemViewType(int position) {
        if (viewTypes.get(position).getType() == HEADER_TYPE) {
            return HEADER_TYPE;
        } else {
            return ACTIVITY_TYPE;
        }
    }

    @Override
    public void onHeaderClick(int position) {

        ActivityRecyclerViewType viewType = viewTypes.get(position);
        int dataIndex = viewType.getDataIndex();
        String userType = activityHeaderList.get(dataIndex);
        int childCount = numberOfChildrenPerParentNameMap.get(userType);

        if (headerExpandTracker.get(dataIndex) == 0) {
            // Collapsed. Now expand it
            headerExpandTracker.put(dataIndex, 1);
            notifyItemRangeInserted(position + 1, childCount);
            ChooseCategoryActivity.HEADER_EXPANDED_NUMBER = position;
        } else {
            // Expanded. Now collapse it
            headerExpandTracker.put(dataIndex, 0);
            notifyItemRangeRemoved(position + 1, childCount);
            ChooseCategoryActivity.HEADER_EXPANDED_NUMBER = -1;
        }

    }

    @Override
    public boolean isExpanded(int position) {
        int dataIndex = viewTypes.get(position).getDataIndex();
        return headerExpandTracker.get(dataIndex) == 1;
    }

    @Override
    public void onChildClick(String name) {
        if (context instanceof ChooseCategoryActivity) {
            ((ChooseCategoryActivity) context).finishChoosingActivity(name);
        }
    }
}

我尝试过使用recyclerView.setHasFixedSize(true),         recyclerView.setItemViewCacheSize(20),         recyclerView.setDrawingCacheEnabled(true),         recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH)adapter.setHasStableIds(true)对性能没有影响。

必要时可以发布其他组件。

0 个答案:

没有答案