Android在RecyclerView中突出显示一项

时间:2015-07-03 18:04:44

标签: android

我在stackoverflow上对RecyclerView中项目的突出显示提出了几个问题,但我无法实现任何目标,但我的问题应该更容易,因为我只想突出显示一个项目。我成功地做了一些工作,但它突出了回收的项目。

    musicList.addOnItemTouchListener(
            new RecyclerItemClickListener(getApplicationContext(), new RecyclerItemClickListener.OnItemClickListener() {
                @Override
                public void onItemClick(View view, final int position) {

                    view.setBackgroundColor(Color.argb(40,100,100,230));
                }
            })
    );

我的适配器看起来像这样:

公共类MyAdapter扩展了RecyclerView.Adapter {     private String [] mDataset;

// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class ViewHolder extends RecyclerView.ViewHolder {
    // each data item is just a string in this case
    public TextView mTextView;
    public ImageView mp3Icon;
    public ViewHolder(View v) {
        super(v);
        mTextView = (TextView) v.findViewById(R.id.textView);
        mp3Icon = (ImageView) v.findViewById(R.id.iconMp3);

        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(musicPlayer.conv.toPixels(25), musicPlayer.conv.toPixels(30));
        params.setMargins(10,20,20,10);
        mp3Icon.setLayoutParams(params);
    }

}

// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(String[] myDataset) {
    mDataset = myDataset;
}

// Create new views (invoked by the layout manager)
@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                               int viewType) {
    // create a new view
    View v = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.text_layout, parent, false);
    // set the view's size, margins, paddings and layout parameters

    ViewHolder vh = new ViewHolder(v);
    return vh;

}

// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    // - get element from your dataset at this position
    // - replace the contents of the view with that element
    holder.mTextView.setText(mDataset[position]);

}

// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
    return mDataset.length;
}

}

还有我的点击监听器类:

public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
    private OnItemClickListener mListener;

    public interface OnItemClickListener {
        public void onItemClick(View view, int position);
    }

    GestureDetector mGestureDetector;

    public RecyclerItemClickListener(Context context, OnItemClickListener listener) {
        mListener = listener;
        mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }
        });
    }

    @Override public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
        View childView = view.findChildViewUnder(e.getX(), e.getY());
        if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
            mListener.onItemClick(childView, view.getChildPosition(childView));
            return true;
        }
        return false;
    }

    @Override public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { }
}

我的第二次尝试是设置onBindViewHolder

if(selectedItem == position){
    holder.mTextView.setBackgroundColor(Color.argb(40, 100, 100, 230));
}

当我点击列表中的某个项目时,我调用了一个方法并设置了所选项目,但我遇到了同样的问题,选择了两个项目而不是一个。

3 个答案:

答案 0 :(得分:3)

使用此模式:

  • 添加到适配器方法:
/**
 * disable row
 */
public void disableRow(int index) {
    /** 
     *clear array of disabled rows 
     * - remove it if u wanna disable more than one row at once 
     */
    mDisabledRows.clear();
    /** add disabled row to array */
    mDisabledRows.add(index);
    /** refresh view to show background changes - > call getView */
    notifyDataSetChanged();   // for my purpose 
}
  • 声明字段
/** list of disabled rows */
private ArrayList<Integer> mDisabledRows;
  • 在构造函数中初始化字段
/** initialize disabled row array */
mDisabledRows = new ArrayList<>();
  • 在你获取视图的方法中(例如在onBindViewHolder中)使用条件来检查你的项目是否被禁用
/** check if row is disabled */
  if (mDisabledRows.contains(position)) { 
       // do somthing to highlight //
  } else {
     // do something to un-highlight */
  } 
  • 代码使用(如您的CARD案例)
Adapter.disableRow(position) 

<强>说明

适配器将保存所选项目的数组并跟踪给定条件下的更改,然后返回特定视图

答案 1 :(得分:0)

如果未选择颜色,则需要重置颜色。

if(selectedItem == position){
    holder.mTextView.setBackgroundColor(Color.argb(40, 100, 100, 230));
}
else{
    holder.mTextView.setBackgroundColor(defaultColor);
}

答案 2 :(得分:0)

简单的4个步骤即可实现!

  • 在适配器中保留全局变量以跟踪单击位置。
  • 创建具有android:state_activated状态的可选图形。
  • 将此可绘制对象设置为视图背景(也许在您的自定义行中)
  • 设置视图的isActivated属性。

怎么办?

  • 声明全局变量
 private var clickedPos: Int = RecyclerView.NO_POSITION // or any other default int
  • 创建可选
<!-- file name: bg_selector -->
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
 <item android:state_activated="true">
     <shape
         android:shape="rectangle">

         <corners
             android:radius="4dp"/>
         <stroke
             android:width="@dimen/layout_border_width"
             android:color="@color/gray"/>
     </shape>
 </item>

 <item android:state_activated="false">
     <shape
         android:shape="rectangle">

         <corners
             android:radius="4dp"/>
         <stroke
             android:width="@dimen/layout_border_width"
             android:color="@color/white"/>
     </shape>
 </item>
</selector>
  • 在xml中设置背景(不是回收者视图,而是自定义行xml的视图)
android:background="@drawable/bg_selector"
  • 处理点击并在适配器中保持点击位置
 override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
     // other lines

     holder.view.isActivated = position == clickedPos
     holder.view.setOnClickListener {
         clickedPos = position
         notifyDataSetChanged() // Important to call and it notifies of everything
     }
 }