RecylerView onClick获取项目的位置

时间:2015-06-25 14:27:37

标签: java android android-activity android-cardview android-recyclerview

我有RecyclerView持有一堆卡(从网络获取数据,然后填充卡片)。我在获取数据后正确地形成了卡片,但现在我想在每张卡片被点击时设置一个监听器。理想情况下,在每张卡片为clicked后,系统会调用一个新的intent,其中包含有关该卡片数据的更多详细信息。

这是我初始化适配器的地方。 arrList是一个ArrayList,已经从另一个类

填充
private void initializeAdapter() {
    RecycleViewAdapter adapter = new RecycleViewAdapter(arrList);
    rv.setAdapter(adapter);
    }

这是持卡的另一个类:

public class PersonViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener  {

        CardView cv;
        TextView crimeName,crimeID, crimeAddress, crimeDate, crimeWeapon;
        ImageView crimePhoto;

        PersonViewHolder(View itemView) {
            super(itemView);
            cv = (CardView)itemView.findViewById(R.id.cv);

            crimeName = (TextView) itemView.findViewById(R.id.crime_name);
            crimeID = (TextView) itemView.findViewById(R.id.crime_id);
            crimeAddress = (TextView) itemView.findViewById(R.id.crime_address);
            crimeDate = (TextView) itemView.findViewById(R.id.crime_date);
            crimeWeapon = (TextView) itemView.findViewById(R.id.crime_weapon);
            crimePhoto = (ImageView)itemView.findViewById(R.id.crime_photo);

            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View view) {
            // WHAT DO I CALL HERE TO GET THE INDEX OF THE ITEM CLICKED ON ?? //
            Log.d("app", "clicked");

        }
    }

上面的onClick应该转到这个类(通过意图)并传递索引:

    import android.support.v4.app.Fragment;
    import android.support.v7.app.ActionBarActivity;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.ViewGroup;


    public class CrimeDetails extends ActionBarActivity {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_crime_details);
            if (savedInstanceState == null) {
                getSupportFragmentManager().beginTransaction()
                        .add(R.id.container, new PlaceholderFragment())
                        .commit();
            }
        }


        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.crime_details, menu);
            return true;
        }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {

            View rootView = inflater.inflate(R.layout.fragment_crime_details, container, false);
            return rootView;
        }
        }
     }

如何获得卡片的点击位置?

由于

6 个答案:

答案 0 :(得分:4)

net net在onCreateVH方法中设置了onClickListener,但在onBindViewHolder中

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    ((PersonViewHolder)holder).yourRootLayout.setOnClickListener(getPersonClickListener(position));
}

View.OnClickListener getPersonClickListener(final int position) {
    return new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //TODO whatever you want with position
        }
    };
}

编辑: tyczj是对的。将Clicklistener绑定在onBindViewHolder上是一个非常简单但可能不是最好的解决方案 - 但它会起作用!

另一种方法是使用Viewholder本身的getAdapterPosition()方法并将其绑定在onCreateViewHolder中:

@Override
public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
    final View view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.yourLayoutXml, parent, false);
    final ViewHolder holder = new PersonViewHolder(view);
    view.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            final int position = holder.getAdapterPosition();
            //check if position exists
            if (position != RecyclerView.NO_POSITION) {
                //TODO whatever you want
            }
        }
    });
    return holder;
}

答案 1 :(得分:3)

您在getAdapterPosition()

中使用ViewHolder

答案 2 :(得分:2)

我这样做略有不同,使用不同的onClick调用,然后我可以使用

  

getAdapterPosition()

确定点击了哪个项目的方法。

    public static class MyViewHolder extends RecyclerView.ViewHolder {
    ...

        RelativeLayout myLayout = (RelativeLayout) v.findViewById(R.id.device_adap_layout);
        myLayout.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Context cxt = myLayout.getContext();                        
                        final Intent i = new Intent(cxt, NextActivity.class);
                        i.putExtra("ITEMNAME", mAdapterList.get(getAdapterPosition()));
                        cxt.startActivity(i, options.toBundle());
                    }
                });
    ...
    }

答案 3 :(得分:1)

创建扩展Recycle视图并覆盖所需方法的适配器类:

public class Adapter扩展了RecyclerView.Adapter "<" Adapter.AdapterViewHolder">" {

public List<Object> Items;
private Context context;

public Adapter(List<Object> items, Context context) {
    Items = items;
    this.context = context;
}

@Override
public int getItemCount() {
    return comentsItems.size();
}

@Override
public void onBindViewHolder(final AdapterViewHolder hd, int position) {
   int indexOfCard = position;
hd.itemText.setText("pos: "+ position);
}


@Override
public AdapterViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    View itemView = LayoutInflater.
            from(viewGroup.getContext()).
            inflate(R.layout.item_layout, viewGroup, false);

    return new AdapterViewHolder(itemView);
}

public static class AdapterViewHolder extends RecyclerView.ViewHolder {
    protected TextView itemText;
    public AdapterViewHolder(View v) {
        super(v);
  itemText = (TextView)v.findViewById(R.id. itemText);   
  }
}

}

答案 4 :(得分:0)

您应该在onClickListener中设置onBindViewHolder已有位置的地方:

@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
    holder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (listener != null) {
                listener.onItemSelected(position);
            }
        }
    });
}

编辑: 就像@tyczj所说的那样,RecyclerView最好在getAdapterPosition中使用ViewHolder

答案 5 :(得分:0)

使用数据填充cardView时,您还可以使用View的setTag()方法存储位置。由于在调用onClick时您将获得View,您只需在View上调用getTag()来检索位置。