【发布时间】:2015-02-21 21:48:31
【问题描述】:
我正在想办法实现和
一样的效果mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
在 RecyclerView 实现中。请帮忙。
【问题讨论】:
标签: android listview android-recyclerview android-checkbox
我正在想办法实现和
一样的效果mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
在 RecyclerView 实现中。请帮忙。
【问题讨论】:
标签: android listview android-recyclerview android-checkbox
没有对带有RecyclerView 的“选择模式”结构的内置支持。您的选择是自己滚动或使用提供它的第三方库。
DynamicRecyclerView library 提供了选择模式,但我没有尝试过。
This sample app 演示了自己实现它,在这种情况下,使用激活状态来指示哪个是当前选择。整体格局是:
让您的 RecyclerView.ViewHolder 检测指示选择的 UI 操作(单击行?单击行中的 RadioButton?等等)。
在RecyclerView.Adapter 级别跟踪选择。在我的例子中,ChoiceCapableAdapter 与实现 ChoiceMode 策略的 SingleChoiceMode 类一起处理。
当做出选择时,更新新选择的行以反映选择并且更新先前选择的行以反映它不再被选择。 findViewHolderForPosition() on RecyclerView 可以在这里提供帮助 - 如果您跟踪最后一个选择的 position,findViewHolderForPosition() 可以为您提供该选择的 ViewHolder,因此您可以“取消选择”它。
通过将其置于管理RecyclerView的活动或片段的已保存实例状态,跟踪配置更改中的选择。
【讨论】:
findViewHolderForAdapterPosition(),因为这似乎比findViewHolderForLayoutPosition() 更保守一些。现在已弃用的 findViewHolderForPosition() 实际上与 findViewHolderForLayoutPosition() 具有相同的行为,因此后者可以工作,但它不会考虑任何正在进行的数据集更改。
findViewHolderForAdapterPosition() 和 findViewHolderForLayoutPosition() 在您的示例应用程序中似乎具有相同的效果,但我不明白它们之间的区别
notifyDataSetChanged() 调用,findViewHolderForAdapterPosition() 将返回 null。 findViewHolderForLayoutPosition() 完全依赖于 RelativeLayout 的实际可见子代。因此,对于我的示例,可能没有净差异。
findViewHolderForLayoutPosition(),因为无论notifyDataSetChanged()是否已应用,我都需要每次返回一个项目
我已经为这种应用于 RecyclerView 的选择模式创建了一个库,也许它可以提供帮助:
创建此库是为了帮助将多选选择集成到 RecyclerView
与 Gradle 的集成非常简单,只需要 jcenter 仓库和库即可:
repositories {
jcenter()
}
...
dependencies {
compile 'com.davidecirillo.multichoicerecyclerview:multichoicerecyclerview:1.0.1'
}
将 MultiChoiceRecyclerView 添加到您的 xml 文件中
<com.davidecirillo.multichoicesample.MultiChoiceRecyclerView
android:id="@+id/multiChoiceRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
实例化你的对象并连接视图
MultiChoiceRecyclerView mMultiChoiceRecyclerView = (MultiChoiceRecyclerView) findViewById(R.id.multiChoiceRecyclerView);
将您的适配器扩展到 MultiChoiceAdapter 并按照正常使用将其添加到 RecyclerView
public class MyAdapter extends MultiChoiceAdapter<MyViewHolder> {
public MyAdapter(ArrayList<String> stringList, Context context) {
this.mList = stringList;
this.mContext = context;
}
...
}
MyAdapter myAdapter = new MyAdapter(mList, getApplicationContext());
mMultiChoiceRecyclerView.setAdapter(myAdapter);
如需更多信息和定制: https://github.com/dvdciri/MultiChoiceRecyclerView
【讨论】:
你可以按照这个:
– 数据(字符串名称,选择布尔值)
– 带有 itemClickListener 的适配器
– 活动或片段
--activity_main(recyclerView)
--list_item (TextView, CheckBox)
数据
public class MultipleData {
private String mTitle;
private boolean mBoolean;
public MultipleData(String title, boolean mBoolean) {
this.mTitle = title;
this.mBoolean = mBoolean;
}
public String getTitle() {
return mTitle;
}
public void setTitle(String mTitle) {
this.mTitle = mTitle;
}
public boolean isBoolean() {
return mBoolean;
}
public void setBoolean(boolean mBoolean) {
this.mBoolean = mBoolean;
}
}
您的意见 activity_main.xml (recyclerView)
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.thedeveloperworldisyours.fullrecycleview.multiple.MultipleFragment">
<android.support.v7.widget.RecyclerView
android:id="@+id/multiple_fragment_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
和 list_item.xml (TextView, CheckBox)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/multiple_list_item_text"
android:layout_width="match_parent"
android:layout_height="90dp"
android:text="@string/app_name"
android:typeface="monospace"
android:layout_toLeftOf="@+id/multiple_list_item_check_button"
android:gravity="center"
android:textSize="@dimen/multiple_list_item_size_rock_stars"/>
<RadioButton
android:id="@+id/multiple_list_item_check_button"
android:layout_width="wrap_content"
android:layout_height="90dp"
android:layout_alignParentRight="true"
android:checked="false"
android:clickable="false"
android:focusable="false" />
</RelativeLayout>
带有 ClickListener 的适配器
public class MultipleRecyclerViewAdapter extends RecyclerView
.Adapter<MultipleRecyclerViewAdapter
.DataObjectHolder> {
private List<MultipleData> mList;
private static MultipleClickListener sClickListener;
MultipleRecyclerViewAdapter(List<MultipleData> mList) {
this.mList = mList;
}
static class DataObjectHolder extends RecyclerView.ViewHolder
implements View
.OnClickListener {
TextView mTextView;
RadioButton mRadioButton;
DataObjectHolder(View itemView) {
super(itemView);
mTextView = (TextView) itemView.findViewById(R.id.multiple_list_item_text);
mRadioButton = (RadioButton) itemView.findViewById(R.id.multiple_list_item_check_button);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
sClickListener.onItemClick(getAdapterPosition(), v);
}
}
void changedData(int position) {
if (mList.get(position).isBoolean()) {
mList.get(position).setBoolean(false);
} else {
mList.get(position).setBoolean(true);
}
notifyDataSetChanged();
}
void setOnItemClickListener(MultipleClickListener myClickListener) {
this.sClickListener = myClickListener;
}
@Override
public DataObjectHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.multiple_list_item, parent, false);
DataObjectHolder dataObjectHolder = new DataObjectHolder(view);
return dataObjectHolder;
}
@Override
public void onBindViewHolder(DataObjectHolder holder, int position) {
holder.mTextView.setText(mList.get(position).getTitle());
holder.mRadioButton.setChecked(mList.get(position).isBoolean());
}
@Override
public int getItemCount() {
return mList.size();
}
interface MultipleClickListener {
void onItemClick(int position, View v);
}
}
活动或片段
public class MultipleFragment extends Fragment implements MultipleRecyclerViewAdapter.MultipleClickListener{
MultipleRecyclerViewAdapter mAdapter;
public MultipleFragment() {
// Required empty public constructor
}
public static MultipleFragment newInstance() {
return new MultipleFragment();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.multiple_fragment, container, false);
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.multiple_fragment_recycler_view);
MultipleData hendrix = new MultipleData("Jimi Hendrix", false);
MultipleData bowie = new MultipleData("David Bowie", false);
MultipleData morrison = new MultipleData("Jim Morrison", false);
MultipleData presley = new MultipleData("Elvis Presley", false);
MultipleData jagger = new MultipleData("Mick Jagger", false);
MultipleData cobain = new MultipleData("Kurt Cobain", false);
MultipleData dylan = new MultipleData("Bob Dylan", false);
MultipleData lennon = new MultipleData("John Lennon", false);
MultipleData mercury = new MultipleData("Freddie Mercury", false);
MultipleData elton = new MultipleData("Elton John", false);
MultipleData clapton = new MultipleData("Eric Clapton", false);
List<MultipleData> list = new ArrayList<>();
list.add(0, hendrix);
list.add(1, bowie);
list.add(2, morrison);
list.add(3, presley);
list.add(4, jagger);
list.add(5, cobain);
list.add(6, dylan);
list.add(7, lennon);
list.add(8, mercury);
list.add(9, elton);
list.add(10, clapton);
mAdapter = new MultipleRecyclerViewAdapter(list);
recyclerView.setAdapter(mAdapter);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
mAdapter.setOnItemClickListener(this);
return view;
}
@Override
public void onItemClick(int position, View v) {
mAdapter.changedData(position);
}
}
你可以看到this example in GitHub和this post for multiple choice,还有this post for single choice快乐码!!!
【讨论】: