简体   繁体   中英

how to get the position of an Item of the recyclerView when touched

I have a recyclerView inside a DrawerLayout . Each row item has an ImageView , the icon and a Textbox , the text. I use addOnItemTouchListener to detect the position of the row item when clicked by the user , in order to open a new fragment. This is my code from addOnItemTouchListener :

mRecyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
        @Override
        public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
            View item = rv.findChildViewUnder(e.getX(),e.getY()); //finding the view that clicked , using coordinates X and Y
            int position = rv.getChildLayoutPosition(item); //getting the position of the item inside the list
            //Log.d("billy",String.valueOf(position));
            onListViewItemClick(position);
            mDrawer.closeDrawers(); // closing the navigation drawer
            return true;
        }

        @Override
        public void onTouchEvent(RecyclerView rv, MotionEvent e) {

        }

        @Override
        public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

        }
    });

And this is the method onListViewItemClick :

public void onListViewItemClick(int position) {
    DrawerItem data = mList.get(position); //Item of the recycler View at specific position
    Bundle lbundle = new Bundle();
    lFragmentManager = getFragmentManager();
    lFragment = lFragmentManager.findFragmentById(R.id.frame_container);
    lFragment = new FragmentHome();
    lbundle.putSerializable("Item", data); // sending to fragment the Item of the Recycler View , which pressed
    lFragment.setArguments(lbundle);
    //To the fragment
    lFragmentManager.beginTransaction().replace(R.id.frame_container ,lFragment ).commit();
}

The problem is that this implementation works only if the user clicks the imageView of the row item of the Navigation Drawer. If the user clicks in the TextView of the row Item then the variable position takes the value -1 . I thing that the method findChildViewUnder(e.getX(), e.getY()) to return only the imageView and not both. I want findChildViewUnder(e.getx(),e.getY()) returns the viewGroup.

This is the XML file that defines each row - Item of the Navigation Drawer:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:orientation="horizontal"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:background="?android:attr/selectableItemBackground">
<LinearLayout
    android:id="@+id/inner_layout"
    android:layout_width="40dp"
    android:layout_height="wrap_content"
    android:layout_alignBottom="@+id/nv_title"
    android:layout_alignTop="@+id/nv_title"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true">

    <ImageView
        android:layout_width="25dp"
        android:layout_height="25dp"
        android:id="@+id/nv_image"
        android:background="@android:color/transparent"
        android:scaleType="fitXY"
        android:layout_marginLeft="15dp"
        android:layout_gravity="center"/>

</LinearLayout>

<TextView
    android:id="@+id/nv_title"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="13dp"
    android:minHeight="?android:attr/listPreferredItemHeightSmall"
    android:textAppearance="?android:attr/textAppearanceListItemSmall"
    android:gravity="center_vertical"
    android:layout_centerVertical="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentEnd="true"
    android:layout_toEndOf="@+id/inner_layout"
    android:layout_gravity="center"
    android:singleLine="true"
    android:ellipsize="end"
    android:layout_toRightOf="@+id/inner_layout" />

    </RelativeLayout>

Thank you for the Help!

If you had registed ItemTouchListener you can get view position as following:

public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
    private static final String TAG = RecyclerItemClickListener.class.getSimpleName();

    public void setListener(OnItemClickListener mListener) {
        this.mListener = mListener;
    }

    private OnItemClickListener mListener;

    public RecyclerItemClickListener(Context context) {
        this(context, null);
    }


    GestureDetector mGestureDetector;

    public RecyclerItemClickListener(Context context, OnItemClickListener listener) {
        mListener = listener;
        mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }
        });
    }

    @Override public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
        View childView = view.findChildViewUnder(e.getX(), e.getY());

        if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
            mListener.onItemClick(view, childView, view.getChildAdapterPosition(childView));
        }
        return false;
    }

    @Override public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }
}

Statement view.getChildAdapterPosition(childView) is method from RecyclerView and returns the position of touched view in the adapter.

You could extend the ViewHolder class to have a click listener on parts of your item that you need to click on (ie use the container to catch "item clicks"). When clicked you can do whatever you like with the event, and the accurate position will be getAdapterPosition() from the ViewHolder itself.

You can gain access to the position if you set your onClick listener on onBindViewHolder

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
//TODO: Use position here.
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM