问题
My RecyclerView is like this
When I Clicked on F-0 and S-0 for selection and changed background. It is also changed background color F-15 and S-15.
My Code is here.
MyRecyclerViewAdapter.java
public class MyRecyclerViewAdapter extends RecyclerView
.Adapter<MyRecyclerViewAdapter
.DataObjectHolder> {
private static String LOG_TAG = "MyRecyclerViewAdapter";
private ArrayList<DataObject> mDataset;
private static MyClickListener myClickListener;
public static class DataObjectHolder extends RecyclerView.ViewHolder
implements View
.OnClickListener {
TextView label;
TextView dateTime;
public DataObjectHolder(View itemView) {
super(itemView);
label = (TextView) itemView.findViewById(R.id.textView);
dateTime = (TextView) itemView.findViewById(R.id.textView2);
Log.i(LOG_TAG, "Adding Listener");
itemView.setOnClickListener(this);
label.setOnClickListener(this);
dateTime.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if(v.getId() == label.getId()){
label.setBackgroundColor(Color.parseColor("#FFFF00"));
}else if(v.getId() == dateTime.getId()){
dateTime.setBackgroundColor(Color.parseColor("#0000FF"));
}else{
Toast.makeText(v.getContext(), "ROW PRESSED = " + String.valueOf(getAdapterPosition()), Toast.LENGTH_SHORT).show();
}
int position = getAdapterPosition();
Log.i(LOG_TAG, String.valueOf(position));
myClickListener.onItemClick(position, v);
}
}
public void setOnItemClickListener(MyClickListener myClickListener) {
this.myClickListener = myClickListener;
}
public MyRecyclerViewAdapter(ArrayList<DataObject> myDataset) {
mDataset = myDataset;
}
@Override
public DataObjectHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recyclerview_item, parent, false);
DataObjectHolder dataObjectHolder = new DataObjectHolder(view);
return dataObjectHolder;
}
@Override
public void onBindViewHolder(DataObjectHolder holder, int position) {
holder.label.setText(mDataset.get(position).getmText1());
holder.dateTime.setText(mDataset.get(position).getmText2());
}
public void addItem(DataObject dataObj, int index) {
mDataset.add(dataObj);
notifyItemInserted(index);
}
public void deleteItem(int index) {
mDataset.remove(index);
notifyItemRemoved(index);
}
@Override
public int getItemCount() {
return mDataset.size();
}
public interface MyClickListener {
public void onItemClick(int position, View v);
}
}
DataObject.java
public class DataObject {
private String mText1;
private String mText2;
DataObject (String text1, String text2){
mText1 = text1;
mText2 = text2;
}
public String getmText1() {
return mText1;
}
public void setmText1(String mText1) {
this.mText1 = mText1;
}
public String getmText2() {
return mText2;
}
public void setmText2(String mText2) {
this.mText2 = mText2;
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private static String LOG_TAG = "RecyclerViewActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new MyRecyclerViewAdapter(getDataSet());
mRecyclerView.setAdapter(mAdapter);
RecyclerView.ItemDecoration itemDecoration =
new DividerItemDecoration(this, LinearLayoutManager.VERTICAL);
mRecyclerView.addItemDecoration(itemDecoration);
}
@Override
protected void onResume() {
super.onResume();
((MyRecyclerViewAdapter) mAdapter).setOnItemClickListener(new
MyRecyclerViewAdapter.MyClickListener() {
@Override
public void onItemClick(int position, View v) {
Log.i(LOG_TAG, " Clicked on Item " + position);
}
});
}
private ArrayList<DataObject> getDataSet() {
ArrayList results = new ArrayList<DataObject>();
for (int index = 0; index < 20; index++) {
DataObject obj = new DataObject("F-" + index,
"S-" + index);
results.add(index, obj);
}
return results;
}
}
So, can you please guide me how to select item for only one row?
Thanks in advance.
回答1:
onBindViewHolder freely recycles Views used by the adapter.
So if you had:
DataObjectHolder X set to View A, and DataObjectHolder Y set to View B
and you changed the background for Holder X, it actually changed it on View A, the same view can be then used by Holder Y, showing the wrong background.
So what you need to do, is store the state on DataObjectHolder, and in onBindViewHolder check the state and refresh the background color appropriately.
EDIT:
The ViewHolder:
public static class DataObjectHolder extends RecyclerView.ViewHolder
implements View
.OnClickListener {
TextView label;
TextView dateTime;
int labelColor = Color.RED;
int dateColor = Color.RED;
public DataObjectHolder(View itemView) {
super(itemView);
...
}
@Override
public void onClick(View v) {
if (v.getId() == label.getId()) {
labelColor = Color.BLUE;
} else if(v.getId() == dateTime.getId()) {
dateColor = Color.BLUE;
} else {
...
}
adapter.notifyDataSetChanged();
// or use notifyItemChanged(pos) if you know the position of the view
}
}
In the Adapter code:
@Override
public void onBindViewHolder(DataObjectHolder holder, int position) {
holder.label.setText(mDataset.get(position).getmText1());
holder.dateTime.setText(mDataset.get(position).getmText2());
// refresh the background color based on the value stored in holder:
holder.label.setBackgroundColor(holder.labelColor);
holder.dateTime.setBackgroundColor(holder.dateColor);
}
回答2:
After worked few days on the issue, I have finally solved it before few months. But I was busy with some work. So, I posted it late. Instead of Recyclerview, I have have used Listview. But I think it should also work with Recyclerview. Also, I changed example and put it here. click to view output
Please find code for above example.
MainActivity.Java
package com.example.listviewapplication;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.ListViewCompat;
import android.util.Log;
import android.widget.ListView;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private ListView listView;
ContentAdapter contentAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView)findViewById(R.id.listview);
contentAdapter = new ContentAdapter(getApplicationContext(),R.layout.row_layout);
listView.setAdapter(contentAdapter);
for (int index = 0; index < 60; index++) {
Content content = new Content(index+1,"A-" + index,
"B-" + index,"C-"+index);
contentAdapter.add(content);
contentAdapter.notifyDataSetChanged();
}
}
}
ContentAdapter.java
Please make sure that ContactHoder declare as final.
package com.example.listviewapplication;
import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
public class ContentAdapter extends ArrayAdapter{
ArrayList list = new ArrayList();
private HashMap mIdToPosition;
public ContentAdapter(Context context, int resource) {
super(context, resource);
init();
}
private void init() {
mIdToPosition = new HashMap();
}
public void add(Content object) {
super.add(object);
list.add(object);
}
@Override
public int getCount() {
//return super.getCount();
return list.size();
}
@Override
public Object getItem(int position) {
//return super.getItem(position);
return list.get(position);
}
@Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
View row;
row = convertView;
final ContactHolder contactHolder;
if(row == null){
LayoutInflater layoutInflater = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = layoutInflater.inflate(R.layout.row_layout,parent,false);
contactHolder = new ContactHolder();
contactHolder.tx_data1 = (TextView)row.findViewById(R.id.tx_data1);
contactHolder.tx_data2 = (TextView)row.findViewById(R.id.tx_data2);
contactHolder.tx_data3 = (TextView)row.findViewById(R.id.tx_data3);
row.setTag(contactHolder);
}else{
contactHolder = (ContactHolder)row.getTag();
}
Content content = (Content) this.getItem(position);
//get DataId as unique value, it is set from MainActivity for loop
Integer dataId = content.getDataId();
contactHolder.tx_data1.setText(content.getData1());
contactHolder.tx_data1.setTag(dataId+"-"+content.getData1()+"-"+position+"-1");
contactHolder.tx_data2.setText(content.getData2());
contactHolder.tx_data2.setTag(dataId+"-"+content.getData2()+"-"+position+"-2");
contactHolder.tx_data3.setText(content.getData3());
contactHolder.tx_data3.setTag(dataId+"-"+content.getData3()+"-"+position+"-3");
//check hashmap key (dataId) for already data is in listview or not
//if textview was selected then check which textview is selected otherwise all textview has default color
if(mIdToPosition.containsKey(dataId)){
Log.d("containsKey",mIdToPosition.get(dataId).toString());
String x = mIdToPosition.get(dataId).toString();
String[] newarr = x.split("-");
Integer mid = Integer.parseInt(newarr[0]);
Integer pos = Integer.parseInt(newarr[3]);
Integer textid = Integer.parseInt(newarr[4]);
//Set Default Color for all textviews
// contactHolder.tx_data1.setBackgroundResource(R.color.colorPrimaryDark);
// contactHolder.tx_data2.setBackgroundResource(R.color.colorPrimaryDark);
// contactHolder.tx_data3.setBackgroundResource(R.color.colorPrimaryDark);
//check textview id and accordingly set color for selected textview
switch (textid) {
case 1:
contactHolder.tx_data1.setBackgroundResource(R.color.colorAccent);
contactHolder.tx_data1.setSelected(true);
break;
case 2:
contactHolder.tx_data2.setBackgroundResource(R.color.colorAccent);
contactHolder.tx_data2.setSelected(true);
break;
case 3:
contactHolder.tx_data3.setBackgroundResource(R.color.colorAccent);
contactHolder.tx_data3.setSelected(true);
break;
}
}
else{
contactHolder.tx_data1.setBackgroundResource(R.color.colorPrimaryDark);
contactHolder.tx_data2.setBackgroundResource(R.color.colorPrimaryDark);
contactHolder.tx_data3.setBackgroundResource(R.color.colorPrimaryDark);
}
//Set OnclickListner for all Textviews
View.OnClickListener onClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
String s = v.getTag().toString();
String[] arr = s.split("-");
//if textview already selected then unselect and set default color of textview.
if(v.isSelected()){
v.setBackgroundResource(R.color.colorPrimaryDark);
v.setSelected(false);
mIdToPosition.remove(Integer.parseInt(arr[0]));
}else{
switch (v.getId()){
case R.id.tx_data1:
v.setBackgroundResource(R.color.colorAccent);
v.setSelected(true);
//Store dataId key in hashmap (DataId is unique id)
mIdToPosition.put(Integer.parseInt(arr[0]),s);
contactHolder.tx_data2.setBackgroundResource(R.color.colorPrimaryDark);
contactHolder.tx_data3.setBackgroundResource(R.color.colorPrimaryDark);
break;
case R.id.tx_data2:
v.setBackgroundResource(R.color.colorAccent);
v.setSelected(true);
//Store dataId key in hashmap (DataId is unique id)
mIdToPosition.put(Integer.parseInt(arr[0]),s);
contactHolder.tx_data1.setBackgroundResource(R.color.colorPrimaryDark);
contactHolder.tx_data3.setBackgroundResource(R.color.colorPrimaryDark);
break;
case R.id.tx_data3:
v.setBackgroundResource(R.color.colorAccent);
v.setSelected(true);
//Store dataId key in hashmap (dataId is unique id)
mIdToPosition.put(Integer.parseInt(arr[0]),s);
contactHolder.tx_data1.setBackgroundResource(R.color.colorPrimaryDark);
contactHolder.tx_data2.setBackgroundResource(R.color.colorPrimaryDark);
break;
}
}
}
};
contactHolder.tx_data1.setOnClickListener(onClickListener);
contactHolder.tx_data2.setOnClickListener(onClickListener);
contactHolder.tx_data3.setOnClickListener(onClickListener);
return row;
}
static class ContactHolder{
TextView tx_data1, tx_data2, tx_data3;
}
}
Content.java
package com.example.listviewapplication;
public class Content {
private String data1,data2,data3;
private Integer dataId;
public Content (Integer dataId,String data1,String data2,String data3){
this.setData1(data1);
this.setData2(data2);
this.setData3(data3);
this.setDataId(dataId);
}
public String getData1() {
return data1;
}
public void setData1(String data1) {
this.data1 = data1;
}
public String getData2() {
return data2;
}
public void setData2(String data2) {
this.data2 = data2;
}
public String getData3() {
return data3;
}
public void setData3(String data3) {
this.data3 = data3;
}
public Integer getDataId(){
return dataId;
}
public void setDataId(Integer dataId){
this.dataId = dataId;
}
}
Please let me know, if any one required further assistance on it.
来源:https://stackoverflow.com/questions/37463862/recyclerview-setonclicklistener-on-textview-changes-background-of-another-row-te