好的,我再尝试一次。上次我问有关在recyclerview和物料之间传递数据的问题,一个人通过单击帮助我打开了物料,但我仍然不知道如何在新活动中显示单击物料的数据。我想单击一个项目,然后在新活动中显示该项目的数据。在此活动中,我要编辑数据。 有谁知道该怎么做?我有任何想法。
具有OnItemClickListener接口的RecyclerView适配器:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.TaskViewHolder> {
private List<MainViewModel> mTasks;
private List<Task> tasks = new ArrayList<>();
private Context context;
private EditTaskViewModel editTaskViewModel;
public RecyclerViewAdapter(List<MainViewModel> tasks, Context context, EditTaskViewModel editTaskViewModel) {
this.mTasks = tasks;
this.context = context;
this.editTaskViewModel = editTaskViewModel;
}
@NonNull
@Override
public RecyclerViewAdapter.TaskViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
final RecyclerViewItemBinding binding = DataBindingUtil.inflate(inflater, R.layout.recycler_view_item, parent, false);
binding.setItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(View view) {
Intent intent = new Intent(view.getContext(), EditTaskActivity.class);
intent.putExtra("id", binding.getPosition());
view.getContext().startActivity(intent);
Toast.makeText(view.getContext(), "ID " + binding.getPosition(), Toast.LENGTH_SHORT).show();
}
});
return new TaskViewHolder(binding);
}
@Override
public void onBindViewHolder(@NonNull final RecyclerViewAdapter.TaskViewHolder holder, final int position) {
Task currentTask = tasks.get(position);
holder.mBinding.descriptionItem.setText(currentTask.getDescription());
holder.mBinding.dateItem.setText(currentTask.getDate());
holder.mBinding.timeItem.setText(currentTask.getTime());
holder.mBinding.setPosition(position);
}
@Override
public int getItemCount() {
return tasks.size();
}
public void setTasks(List<Task> tasks) {
this.tasks = tasks;
notifyDataSetChanged();
}
public Task getTaskPosition(int position) {
return tasks.get(position);
}
public class TaskViewHolder extends RecyclerView.ViewHolder {
private final RecyclerViewItemBinding mBinding;
public TaskViewHolder(RecyclerViewItemBinding binding) {
super(binding.getRoot());
this.mBinding = binding;
}
public void bind (MainViewModel mainViewModel){
mBinding.setItemView(mainViewModel);
mBinding.executePendingBindings();
}
}
public interface OnItemClickListener {
void onItemClick(View view);
}
项目XML文件:
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="itemView"
type="com.example.daniellachacz.taskmvvm.viewmodel.MainViewModel">
</variable>
<variable
name="itemClickListener"
type="com.example.daniellachacz.taskmvvm.adapter.RecyclerViewAdapter.OnItemClickListener">
</variable>
<variable
name="task"
type="com.example.daniellachacz.taskmvvm.model.Task">
</variable>
<variable
name="position"
type="int">
</variable>
</data>
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="120dp"
android:shadowColor="@color/colorPrimary"
android:backgroundTint="@color/cardview_shadow_end_color">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="110dp"
android:layout_marginBottom="6dp"
android:layout_marginTop="6dp"
android:layout_marginStart="6dp"
android:layout_marginEnd="6dp"
android:onClick="@{(view)-> itemClickListener.onItemClick(view)}">
<TextView
android:id="@+id/description_item"
android:layout_width="250dp"
android:layout_height="96dp"
android:layout_marginStart="5dp"
android:layout_marginTop="9dp"
android:layout_marginBottom="5dp"
android:text="@{itemView.description}"
android:textSize="18sp"
android:textColor="#020202"
android:focusable="true" />
<TextView
android:id="@+id/date_item"
android:layout_width="90dp"
android:layout_height="40dp"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_marginTop="9dp"
android:layout_marginEnd="10dp"
android:gravity="center"
android:text="@{itemView.date}"
android:textColor="#020202"
android:textSize="16sp" />
<TextView
android:id="@+id/time_item"
android:layout_width="90dp"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:layout_alignStart="@+id/date_item"
android:layout_marginBottom="10dp"
android:layout_marginEnd="10dp"
android:gravity="center"
android:text="@{itemView.time}"
android:textColor="#020202"
android:textSize="16sp" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</layout>
onCreate:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
floatingActionButton = findViewById(R.id.floating_action_button);
List<Task> tasks = new ArrayList<>();
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
final RecyclerViewAdapter recyclerViewAdapter = new RecyclerViewAdapter(context, tasks);
recyclerView.setAdapter(recyclerViewAdapter);
mainViewModel = ViewModelProviders.of(this).get(MainViewModel.class);
mainViewModel.getAllTasks().observe(this, recyclerViewAdapter::setTasks);
答案 0 :(得分:0)
这取决于数据的存储方式以及在第二个活动中是否可以访问。如果您的数据具有静态ArrayList,则可以使用在RV项目的onclick中传递的索引从数据中提取数据。例如:
class myData{
private ArrayList<Data> myDataArray;
static ArrayList<Data> getMyDataArray(){
return myDataArray;
}
static void setMyDataArray(array)
myDataArray = array;
}
因此,您用getMyDataArray()填充RV,然后设置onlclick以将RV中单击的索引发送到下一个活动。 在第二个活动的onLoad中:
int myDataIndex = getIntent().getIntExtra("id",0);
Data myData = myData.getMyDataArray().get(myDataIndex);
注意:数据就是您的数据,可以是字符串,整数或带有数据的自定义类/对象。
答案 1 :(得分:0)
以下是一些您可能会觉得有用的建议:
不依赖适配器中的ViewModel
。 ViewModel
用于处理视图(片段或活动)中的事件,并通过某种可观察的机制(最常见的LiveData
实例)将更新广播回视图。直接在适配器内部引用ViewModel
是不好的,因为它将它们耦合在一起。这意味着如果需要,您将很难用另一个ViewModel
重用适配器。我知道目前似乎不太可能,但请相信我。应用更改后,您的适配器应如下所示:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.TaskViewHolder> {
private LayoutInflater mLayoutInflater;
private List<Task> mTasks;
private OnItemClickListener mOnItemClickListener;
public RecyclerViewAdapter(@NonNull Context context, @NonNull List<Task> tasks) {
mLayoutInflater = LayoutInflater.fromContext(context);
mTasks = tasks;
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
mOnItemClickListener = onItemClickListener;
}
@NonNull
@Override
public RecyclerViewAdapter.TaskViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
final RecyclerViewItemBinding binding = DataBindingUtil.inflate(mLayoutInflater, R.layout.recycler_view_item, parent, false);
return new TaskViewHolder(binding);
}
@Override
public void onBindViewHolder(@NonNull final RecyclerViewAdapter.TaskViewHolder holder, final int position) {
Task currentTask = tasks.get(position);
holder.bind(currentTask, mOnItemClickListener);
}
@Override
public int getItemCount() {
return tasks.size();
}
public void setTasks(List<Task> tasks) {
this.tasks = tasks;
notifyDataSetChanged();
}
public Task getTaskPosition(int position) {
return tasks.get(position);
}
public class TaskViewHolder extends RecyclerView.ViewHolder {
private final RecyclerViewItemBinding mBinding;
public TaskViewHolder(RecyclerViewItemBinding binding) {
super(binding.getRoot());
this.mBinding = binding;
}
public void bind (Task item, OnItemClickListener onItemClickListener) {
mBinding.setItem(item);
mBinding.executePendingBindings();
itemView.setOnClickListener(view -> {
if (onItemClickListener != null) {
onItemClickListener.onItemClick(view, item);
}
}
}
}
public interface OnItemClickListener {
void onItemClick(View view, Task item);
}
}
OnItemClickListener.onItemClick()
方法现在将视图和项目本身作为参数传递。这是将单击的项目暴露给任何感兴趣的人的最简单方法。没有使用setOnItemClickListener()
在适配器级别设置on click监听器。
现在通过OnClickListener
的{{1}}方法对项目视图的bind()
进行设置。绑定时,我们知道将要填充视图的确切项目,因此我们可以将其返回到TaskViewHolder
。
您还必须简化布局,因为确实不需要很多东西。可能看起来像这样:
OnItemClickListener
唯一的变量是<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="task"
type="com.example.daniellachacz.taskmvvm.model.Task">
</variable>
</data>
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="120dp"
android:shadowColor="@color/colorPrimary"
android:backgroundTint="@color/cardview_shadow_end_color">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="110dp"
android:layout_marginBottom="6dp"
android:layout_marginTop="6dp"
android:layout_marginStart="6dp"
android:layout_marginEnd="6dp">
<TextView
android:id="@+id/description_item"
android:layout_width="250dp"
android:layout_height="96dp"
android:layout_marginStart="5dp"
android:layout_marginTop="9dp"
android:layout_marginBottom="5dp"
android:text="@{item.description}"
android:textSize="18sp"
android:textColor="#020202"
android:focusable="true" />
<TextView
android:id="@+id/date_item"
android:layout_width="90dp"
android:layout_height="40dp"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_marginTop="9dp"
android:layout_marginEnd="10dp"
android:gravity="center"
android:text="@{item.date}"
android:textColor="#020202"
android:textSize="16sp" />
<TextView
android:id="@+id/time_item"
android:layout_width="90dp"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:layout_alignStart="@+id/date_item"
android:layout_marginBottom="10dp"
android:layout_marginEnd="10dp"
android:gravity="center"
android:text="@{item.time}"
android:textColor="#020202"
android:textSize="16sp" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</layout>
,我们将其属性绑定到item
。
我想这应该足以使您前进。
还有其他与问题没有直接关系但很重要的其他事情。
TextView
时永远不会检查输入。客户可能会通过setTask()
并导致整个地方崩溃。您应该尝试防止这种情况。null
时,调用notifyDataSetChanged()
不是一个好习惯,因为这会取消RecyclerView.Adapter
的所有内置动画。最好使用其他RecyclerView
方法。您可能需要在某个时候检查notify...
。答案 2 :(得分:0)
这是我使用数据绑定为回收者视图中的项目单击侦听器所做的事情。
适配器代码
public class TC_DashboardRecViewAdapter extends RecyclerView.Adapter<TC_DashboardRecViewAdapter.ViewHolder> {
Context context;
List<String> list;
private TcDashboardItemBinding tcDashboardItemBinding;
ItemClickListener itemClickListener;
public TC_DashboardRecViewAdapter(Context context, List<String> dashboardItems, ItemClickListener itemClickListener) {
this.context = context;
this.list = dashboardItems;
this.itemClickListener = itemClickListener;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
ViewDataBinding binding = DataBindingUtil.inflate(inflater, R.layout.tc_dashboard_item, parent, false);
tcDashboardItemBinding = (TcDashboardItemBinding) parent.getTag();
return new ViewHolder(binding);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.bind(list.get(position), itemClickListener, position);
}
@Override
public int getItemCount() {
return list.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
private ViewDataBinding binding;
public ViewHolder(ViewDataBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
public void bind(String s, ItemClickListener itemClickListener, int position) {
this.binding.setVariable(BR.itemModel, s);
this.binding.executePendingBindings();
binding.getRoot().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(itemClickListener !=null){
itemClickListener.onItemClicked(binding.getRoot(), s, position);
}
}
});
}
}
项目点击界面:
public interface ItemClickListener {
void onItemClicked(View vh, Object item, int pos);
}
片段/活动代码:
public class TC_DashboardFragment extends BaseFragment implements ItemClickListener {
public void onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
tc_dashboardRecViewAdapter = new TC_DashboardRecViewAdapter(getContext(), getDashboardItems(), this);
linearLayoutManager = new LinearLayoutManager(getContext());
dashboardrecyclerview.setLayoutManager(new LinearLayoutManager(getContext()));
binding.setAdapter(tc_dashboardRecViewAdapter);
}
@Override
public void onItemClicked(View vh, Object item, int pos) {
Toast.makeText(mainActivity, item.toString(), Toast.LENGTH_SHORT).show();
}
运行代码并单击“回收者视图”项目时,它将显示一个带有该项目中的文本的祝酒词。