RecyclerView 粘性标题 onClick 和滚动条

Tah*_*aha 5 android android-recyclerview

我制作了一个装饰类来在 recyclerview 中创建粘性标题。我有两个问题。

  1. 在听点击时,当一个普通项目在粘性标题下时,粘性标题的点击不起作用。(点击它下面的项目。)
  2. 由于我正在绘制粘性标题,因此它们被绘制到滚动条上并将其隐藏。

所以我想知道我该如何解决这些问题?编写自定义布局管理器是唯一的方法吗?我想不出任何其他解决方案。我什至不确定自定义布局管理器可以解决这个问题。

你可以在下面找到我的装饰课:

package com.done.xrecyclerview.library;

import android.graphics.Canvas;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;

public class StickyHeaderDecoration extends RecyclerView.ItemDecoration
{

private static final boolean D = true;
private static final String TAG = "HeaderDecoration";

private void init()
{
    //Do your initializations here.
}


@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state)
{
    super.onDrawOver(c, parent, state);
    if (parent.getAdapter() != null && parent.getAdapter()
                                             .getItemCount() > 1) //RecylerView's adapter exist and has items.
    {

        View firstView = parent.getChildAt(0); //get the first visible view.
        View secondView = parent.getChildAt(1); //get the second visible view.

        View headerView = getHeaderOf(parent, firstView); //get the first visible view's header.

        if (isHeaderView(parent, secondView)) //if the second view is also a header
        {
            if (secondView.getTop() <= headerView.getHeight())
                c.translate(0,
                        secondView.getTop() - headerView.getHeight()); //translate the canvas
        }

        headerView.draw(c);

        c.save();
        //c.restore();
        c.translate(0, 0);
    }
}

/**
 * Determines whether the given View is a header.
 *
 * @param parent Parent of given view.
 * @param view   View to be checked.
 * @return true if the view is a header, false otherwise
 */
private boolean isHeaderView(RecyclerView parent, View view)
{

    if (parent.getAdapter() instanceof XRecyclerViewAdapter) //check if the adapter of RecyclerView is an instance of our custom adapter.
    {
        int childPosition = parent.getChildPosition(view); //get position of the view in the adapter.
        XRecyclerViewAdapter adapter = (XRecyclerViewAdapter) parent.getAdapter(); //get the adapter itself.
        return adapter.get(childPosition)
                      .getItemType() == XItemTypes.HEADER; //if the item of the position of view is header.
    } else
        return false;
}

/**
 * Checks whether the given position is occupied by a header.
 *
 * @param parent   RecyclerView that contains the given position.
 * @param position Position to be checked.
 * @return true if the position is occupied by a header. false otherwise.
 */
private boolean isHeaderPosition(RecyclerView parent, int position)
{
    XRecyclerViewAdapter adapter = (XRecyclerViewAdapter) parent.getAdapter();
    return adapter.get(position).getItemType() == XItemTypes.HEADER;
}


/**
 * Finds the header of given view.
 *
 * @param parent Parent of the view.
 * @param view   View itself whose header will be found.
 * @return If the given View is already a header, returns that view.
 * If the view doesn't have a header returns null.
 * If the view has a header returns the view's header.
 */
private View getHeaderOf(RecyclerView parent, View view)
{
    if (isHeaderView(parent, view)) //item is already header.
        return view; //return the view.
    else //item is child. Find it's header.
    {
        int position = parent.getChildPosition(view); //get the position of given child item in adapter.
        //Log.i(TAG, "position = " + position);
        XRecyclerViewAdapter adapter = (XRecyclerViewAdapter) parent.getAdapter(); //get the adapter.
        for (int i = position; i >= 0; i--) //iterate backwards from the position of given child item.
        {
            if (isHeaderPosition(parent, i)) //if the iterated position is occupied by a header
            {
                RecyclerView.ViewHolder viewHolder = adapter.onCreateViewHolder(parent,
                        XRecyclerViewAdapter.VIEW_TYPE_HEADER); //create its viewholder.
                adapter.onBindViewHolder(viewHolder, i); //bind its viewholder.

                View header = viewHolder.itemView; //get that header view to set LayoutParams.

                if (header.getLayoutParams() == null) //if the LayoutParams null, initiate it.
                {
                    header.setLayoutParams(new RecyclerView.LayoutParams(
                            LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
                }

                int widthSpec;
                int heightSpec;

                widthSpec = View.MeasureSpec.makeMeasureSpec(parent.getWidth(),
                        View.MeasureSpec.EXACTLY);
                heightSpec = View.MeasureSpec.makeMeasureSpec(parent.getHeight(),
                        View.MeasureSpec.UNSPECIFIED);

                int childWidth = ViewGroup.getChildMeasureSpec(widthSpec,
                        parent.getPaddingLeft() + parent.getPaddingRight(),
                        header.getLayoutParams().width);
                int childHeight = ViewGroup.getChildMeasureSpec(heightSpec,
                        parent.getPaddingTop() + parent.getPaddingBottom(),
                        header.getLayoutParams().height);
                header.measure(childWidth, childHeight);
                header.layout(0, 0, header.getMeasuredWidth(), header.getMeasuredHeight());

                return header;

            }
        }

    }
    return null;
}
}
Run Code Online (Sandbox Code Playgroud)