2017-05-27 28 views
-1

私は、ユーザがRecyclerViewのアイテムを1つまたは複数クリックすると、それらのアイテムが選択されているときに、同じアイテム/アイテムを2回クリックするとそのアイテムが選択解除される機能を実装しようとしています。ユーザがクリックしたアイテムが選択または選択解除されたことをユーザに示すために、画像が表示または非表示にされます。Android - RecyclerViewアイテム選択の問題

ただし、アイテムの1つをクリックするとRecyclerViewが複数選択されています。ここで

は、これまでの私のコードです:

my_list_item.xml

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"> 


    <TextView 
     android:id="@+id/tvTest" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="15dp" 
     android:text="Test" 
     android:textSize="18sp" /> 

    <ImageView 
     android:id="@+id/ivItemIsSelected" 
     android:layout_width="20dp" 
     android:layout_height="20dp" 
     android:layout_alignParentRight="true" 
     android:layout_marginRight="10dp" 
     android:layout_marginTop="10dp" 
     android:src="@drawable/done_256" 
     android:visibility="invisible" /> 

</RelativeLayout> 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context="com.test.www.recyclerviewadaptertest.MainActivity"> 

<android.support.v7.widget.RecyclerView 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:id="@+id/rvTest"/> 

</RelativeLayout> 

MainActivity.java

import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.support.v7.widget.DefaultItemAnimator; 
import android.support.v7.widget.LinearLayoutManager; 
import android.support.v7.widget.RecyclerView; 

import java.util.ArrayList; 


public class MainActivity extends AppCompatActivity { 

    private RecyclerView rvTest; 
    private RecyclerViewTestAdapter recyclerViewTestAdapter; 
    private ArrayList<TestModel> testModels; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     testModels = new ArrayList<>(); 

     for(int i = 0; i < 30; i++){ 
      TestModel testModel = new TestModel("Test nr." + (i+1)); 
      testModels.add(testModel); 
     } 

     recyclerViewTestAdapter = new RecyclerViewTestAdapter(testModels); 
     rvTest = (RecyclerView)findViewById(R.id.rvTest); 
     RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(MainActivity.this); 
     rvTest.setLayoutManager(mLayoutManager); 
     rvTest.setItemAnimator(new DefaultItemAnimator()); 
     rvTest.setAdapter(recyclerViewTestAdapter); 
    } 
} 

RecyclerViewTestAdapterの.javaファイル

import android.support.v7.widget.RecyclerView; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ImageView; 
import android.widget.TextView; 

import java.util.List; 

public class RecyclerViewTestAdapter extends RecyclerView.Adapter<RecyclerViewTestAdapter.MyViewHolder> { 

    private List<TestModel> testModels; 

    public class MyViewHolder extends RecyclerView.ViewHolder { 
     public ImageView ivItemIsSelected; 
     public TextView tvTest; 

     public MyViewHolder(View view) { 
      super(view); 
      ivItemIsSelected = (ImageView) view.findViewById(R.id.ivItemIsSelected); 
      tvTest = (TextView) view.findViewById(R.id.tvTest); 

      view.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        if(ivItemIsSelected.getVisibility() == View.INVISIBLE){ 
         ivItemIsSelected.setVisibility(View.VISIBLE); 
        }else if(ivItemIsSelected.getVisibility() == View.VISIBLE){ 
         ivItemIsSelected.setVisibility(View.INVISIBLE); 
        } 
       } 
      }); 
     } 
    } 

    public RecyclerViewTestAdapter(List<TestModel> testModels) { 
     this.testModels = testModels; 
    } 

    @Override 
    public RecyclerViewTestAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View itemView = LayoutInflater.from(parent.getContext()) 
       .inflate(R.layout.my_list_item, parent, false); 

     return new RecyclerViewTestAdapter.MyViewHolder(itemView); 
    } 

    @Override 
    public void onBindViewHolder(final RecyclerViewTestAdapter.MyViewHolder holder, int position) { 
     TestModel testModel = testModels.get(position); 
     holder.tvTest.setText(testModel.getTestText()); 
    } 

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

TestModel.java

public class TestModel { 

    private String testText; 

    public TestModel() { 
    } 

    public TestModel(String testText) { 
     this.testText = testText; 
    } 

    public String getTestText() { 
     return testText; 
    } 

    public void setTestText(String testText) { 
     this.testText = testText; 
    } 
} 
+0

ViewHolderコンストラクタでアイテムの選択を解除してください。おそらく、リサイクルされ、選択を保持している可能性があります。 –

+0

@NicolasMaltaisあなたの答えをありがとう。私は試しましたが、うまくいきません。 – Nikolaj

答えて

1

それがリサイクルにつれてあなたは、ViewHolderで "選択" 状態を維持するべきではありません。モデルに「選択された」状態を維持します。あなたTestModel.javaを変更: パブリッククラスTestModel {

private String testText; 
public boolean selected = false; 

public TestModel() { 
} 

public TestModel(String testText) { 
    this.testText = testText; 
} 

public String getTestText() { 
    return testText; 
} 

public void setTestText(String testText) { 
    this.testText = testText; 
} 

}

[OnBind]の中のモデルアイテムへの参照を設定し、項目の選択フラグに基づいて可視性を設定:

あり
public class MyViewHolder extends RecyclerView.ViewHolder { 
      public ImageView ivItemIsSelected; 
      public TextView tvTest; 
      private TestModel testModel; 

      public MyViewHolder(View view) { 
       super(view); 
       ivItemIsSelected = (ImageView) view.findViewById(R.id.ivItemIsSelected); 
       tvTest = (TextView) view.findViewById(R.id.tvTest); 

       view.setOnClickListener(new View.OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         testModel.selected = !testModel.selected; 
         ivItemIsSelected.setVisibility(testModel.selected ? View.VISIBLE : View.INVISIBLE); 

        } 
       }); 
      } 
     } 

     public RecyclerViewTestAdapter(List<TestModel> testModels) { 
      this.testModels = testModels; 
     } 

     @Override 
     public RecyclerViewTestAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
      View itemView = LayoutInflater.from(parent.getContext()) 
        .inflate(R.layout.my_list_item, parent, false); 

      return new RecyclerViewTestAdapter.MyViewHolder(itemView); 
     } 

     @Override 
     public void onBindViewHolder(final RecyclerViewTestAdapter.MyViewHolder holder, int position) { 
      testModel = testModels.get(position); 
      holder.tvTest.setText(testModel.getTestText()); 
      holder.ivItemIsSelected.setVisibility(testModel.selected ? View.VISIBLE : View.INVISIBLE); 
     } 

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

これを達成する他の方法ですが、onBindViewHolderが呼び出されるたびに指定された位置に項目を反映させるために、その中のすべてを更新する必要があることを覚えておくことは重要です。お役に立てれば。

+0

ありがとうございます。 – Nikolaj

関連する問題