私は以下のようなRecyclerView
を使用しています:
<Android.support.v7.widget.RecyclerView
Android:id="@+id/list"
Android:layout_width="320dp"
Android:layout_height="match_parent"/>
そして私のリストアイテム:
<LinearLayout Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:background="@drawable/selector_medium_high">
<com.basf.suvinil.crie.ui.common.widget.CircleView
Android:id="@+id/circle"
Android:layout_width="22dp"
Android:layout_height="22dp"/>
<TextView
Android:id="@+id/label"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:minHeight="57.5dp"/>
</LinearLayout>
この部分の詳細を見るAndroid:background="@drawable/selector_medium_high"
これは通常のセレクターです。
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item Android:drawable="@color/background_high" Android:state_activated="true"/>
<item Android:drawable="@color/background_high" Android:state_pressed="true"/>
<item Android:drawable="@color/background_high" Android:state_checked="true"/>
<item Android:drawable="@color/background_high" Android:state_focused="true"/>
<item Android:drawable="@color/background_medium"/>
</selector>
しかし、このコードを実行すると、行をタッチしても背景色に変化はありません。
clickable
"list"のすべての要素で、focusable
、focusableInTouchMode
、true
をRecyclerView
に設定します。
追加 :
Android:background="?android:attr/selectableItemBackground"
item.xml
私にとってはうまくいかなかったように、これがうまくいかない場合は、次のコードを使用します。
Android:foreground="?android:attr/selectableItemBackground"
トリックはAndroid:foreground
属性...
Android:background="?android:attr/selectableItemBackground"
をmy_list_item.xml
の-ルートレイアウトに追加すると、うまくいくようです(デフォルトの選択色が必要な場合)。
また、行全体を選択できるように、ルートレイアウトのAndroid:layout_width
がmatch_parent
ではなくwrap_content
であることを確認してください。
残念ながら、フォーカス可能なビューを使用してアイテム選択をシミュレートすることは、良い解決策ではありません:
notifyDataSetChanged
が呼び出されるとフォーカスが失われます私は、RecyclerViewでアイテムの選択を自動的に処理する基本アダプタークラスを作成しました。アダプターをアダプターから派生させ、リストビューで行うように、state_selectedで描画可能な状態リストを使用するだけです。
Blog Post Here がありますが、コードは次のとおりです。
public abstract class TrackSelectionAdapter<VH extends TrackSelectionAdapter.ViewHolder> extends RecyclerView.Adapter<VH> {
// Start with first item selected
private int focusedItem = 0;
@Override
public void onAttachedToRecyclerView(final RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
// Handle key up and key down and attempt to move selection
recyclerView.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
RecyclerView.LayoutManager lm = recyclerView.getLayoutManager();
// Return false if scrolled to the bounds and allow focus to move off the list
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
return tryMoveSelection(lm, 1);
} else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
return tryMoveSelection(lm, -1);
}
}
return false;
}
});
}
private boolean tryMoveSelection(RecyclerView.LayoutManager lm, int direction) {
int tryFocusItem = focusedItem + direction;
// If still within valid bounds, move the selection, notify to redraw, and scroll
if (tryFocusItem >= 0 && tryFocusItem < getItemCount()) {
notifyItemChanged(focusedItem);
focusedItem = tryFocusItem;
notifyItemChanged(focusedItem);
lm.scrollToPosition(focusedItem);
return true;
}
return false;
}
@Override
public void onBindViewHolder(VH viewHolder, int i) {
// Set selected state; use a state list drawable to style the view
viewHolder.itemView.setSelected(focusedItem == i);
}
public class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View itemView) {
super(itemView);
// Handle item click and set the selection
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Redraw the old selection and the new
notifyItemChanged(focusedItem);
focusedItem = mRecyclerView.getChildPosition(v);
notifyItemChanged(focusedItem);
}
});
}
}
}
viewHolder.mRlPrince.setOnTouchListener(new View.OnTouchListener() {
@Override public boolean onTouch(View v, MotionEvent event) {
if (event.getAction()==MotionEvent.ACTION_DOWN){
viewHolder.mRlPrince.setBackgroundColor(Color.parseColor("#f8f8f8"));
}if (event.getAction()==MotionEvent.ACTION_UP){
viewHolder.mRlPrince.setBackgroundColor(Color.WHITE);
}
return false;
}
});
アイテム「my_list_item.xml」に以下の属性を追加しますAndroid:descendantFocusability="blocksDescendants"
これは私のために働く!
要素xmlでAndroid:clickable="true"
を設定する必要があります。また、ビュー内のいくつかのビューにさらにセレクターがある場合は、そこにもAndroid:duplicateParentState="true"
を設定する必要があります。 Thatsは、事前ハニカムAPIで機能します。
デザインファイルまたはxmlファイルに次の行を配置するだけです。
Android:clickable="true"
Android:focusable="true"
Android:background="?android:attr/activatedBackgroundIndicator"
他の多くの人が答えたように、唯一の方法はセレクタと新しいクラスを組み合わせて選択を追跡することですが、この計算をアダプタに委任することをお勧めします。ライブラリFlexibleAdapterは選択を追跡します。構成の変更にも互換性があります。
さざ波のある背景色は、XML部分なしで実行できますが、動的データを管理するコードで実行できます。
最後に、同じライブラリで多くの機能を使用できます。選択できるのはごく小さな基本機能です。
説明、Wikiページ、完全な動作例をご覧ください。 https://github.com/davideas/FlexibleAdapter