Textview上的Recyclerview setOnClickListener更改了另一行的背景Textview

时间:2016-05-26 14:32:53

标签: android android-recyclerview

我的RecyclerView就像这样

enter image description here

当我点击F-0和S-0进行选择并改变背景时。 它也改变了背景颜色F-15和S-15。

enter image description 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;
}

}

那么,请您指导我如何选择只有一行的项目?

提前致谢。

2 个答案:

答案 0 :(得分:1)

onBindViewHolder可以自由回收适配器使用的Views

所以如果你有: DataObjectHolder X设置为View ADataObjectHolder Y设置为View B 并且您更改了Holder X的背景,它实际上在View A上更改了它,Holder Y可以使用相同的视图,显示错误的背景。

所以你需要做的是将状态存储在DataObjectHolder上,然后在onBindViewHolder中检查状态并适当地刷新背景颜色。

编辑:

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
    }
}

Adapter代码中:

@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);
}

答案 1 :(得分:0)

在这个问题上工作了几天后,我终于在几个月前解决了这个问题。但我忙于一些工作。所以,我发布的很晚。我没有使用Recyclerview,而是使用了Listview。但我认为它也适用于Recyclerview。另外,我改变了例子并把它放在这里。 click to view output

请查找以上示例的代码。

<强> 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

请确保 ContactHoder 声明为最终

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;
    }

}

如果有人需要进一步的帮助,请告诉我。