首页 > 解决方案 > 如何选择 RecyclerView 适配器中的每个项目,以允许我通过转到活动来编辑该列表中的该项目?

问题描述

这是我的第一个问题,所以我会尽力做到最好。

目标是有一个列表,允许我单击每个项目,以便它打开一个新活动,我可以在其中编辑或删除该项目。

目前我有一个选项卡式应用程序,其中我有代表每个选项卡的不同片段,在这些片段中,我有一个要显示的所有项目的回收视图。我还有一个浮动按钮,允许我将新客户端添加到第一个选项卡(客户端)。它看起来像这样:

应用默认主页

我在 YouTube 和博客上尝试了几个视频来解决这个问题,但我无法让它发挥作用。我的愿望是,如果我可以让该点击工作,并且当它打开 UpdateClient 活动时,它会从该项目中获取必要的详细信息。请参阅此处的结构和 UpdateClient 活动:

应用文件结构 更新客户端活动

到目前为止,我已经尝试在片段本身中创建一个按钮,但是当尝试引用编辑按钮的 id(称为“更新”)时,这会返回一个空对象。我也尝试在 RecyclerViewAdapter 中实现 OnClickListener,但也没有运气,它只是随机允许我有时点击,但仍然没有解决我的需求。

这是到目前为止的代码:

主要活动

public class MainActivity extends AppCompatActivity {

private AdminDB_Manager db;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
    ViewPager viewPager = findViewById(R.id.view_pager);
    viewPager.setAdapter(sectionsPagerAdapter);
    TabLayout tabs = findViewById(R.id.tabs);
    tabs.setupWithViewPager(viewPager);
    FloatingActionButton fab = findViewById(R.id.fab);

    // Crear base de datos
    db = new AdminDB_Manager(this);
    db.open();

    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Toast.makeText(MainActivity.this, "Adding Client", Toast.LENGTH_LONG).show();
            addClient(view);
        }
    });
}

public void addClient(android.view.View v) {
    Intent intent = new Intent(this, AddClient.class);
    startActivity(intent);
}
}

客户端片段

public class ClientsFragment extends Fragment {

// TODO: Customize parameter argument names
private static final String ARG_COLUMN_COUNT = "column-count";
// TODO: Customize parameters
private int mColumnCount = 1;

/**
 * Mandatory empty constructor for the fragment manager to instantiate the
 * fragment (e.g. upon screen orientation changes).
 */
public ClientsFragment() {
}

// TODO: Customize parameter initialization
@SuppressWarnings("unused")
public static ClientsFragment newInstance(int columnCount) {
    ClientsFragment fragment = new ClientsFragment();
    Bundle args = new Bundle();
    args.putInt(ARG_COLUMN_COUNT, columnCount);
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (getArguments() != null) {
        mColumnCount = getArguments().getInt(ARG_COLUMN_COUNT);
    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_client_list, container, false);
    Button update = view.findViewById(R.id.update);

    if(update != null){
        update.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(getActivity(), "Adding Client", Toast.LENGTH_LONG).show();
                Intent intent = new Intent(getActivity(), MainActivity.class);
                startActivity(intent);
            }
        });
    }

    // Set the adapter
    if (view instanceof RecyclerView) {
        Context context = view.getContext();
        RecyclerView recyclerView = (RecyclerView) view;
        if (mColumnCount <= 1) {
            recyclerView.setLayoutManager(new LinearLayoutManager(context));
        } else {
            recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount));
        }
        recyclerView.setAdapter(new MyClientsRecyclerViewAdapter(DummyContent.ITEMS));
    }
    return view;
}
}

MyClientsRecyclerViewAdapter

public class MyClientsRecyclerViewAdapter extends RecyclerView.Adapter<MyClientsRecyclerViewAdapter.ViewHolder> {

private final List<DummyItem> mValues;

public MyClientsRecyclerViewAdapter(List<DummyItem> items) {
    mValues = items;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.fragment_clients, parent, false);


    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
    holder.mItem = mValues.get(position);
    holder.mIdView.setText(mValues.get(position).id);
    holder.mContentView.setText(mValues.get(position).content);
}

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

public class ViewHolder extends RecyclerView.ViewHolder {
    public final View mView;
    public final TextView mIdView;
    public final TextView mContentView;
    public DummyItem mItem;

    public ViewHolder(View view) {
        super(view);
        mView = view;
        mIdView = (TextView) view.findViewById(R.id.item_number);
        mContentView = (TextView) view.findViewById(R.id.content);
    }

    @Override
    public String toString() {
        return super.toString() + " '" + mContentView.getText() + "'";
    }
}
}

以下是布局:

片段客户端.xml

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

<TextView
    android:id="@+id/item_number"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="@dimen/text_margin"
    android:textAppearance="?attr/textAppearanceListItem" />

<TextView
    android:id="@+id/content"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="@dimen/text_margin"
    android:textAppearance="?attr/textAppearanceListItem" />

    </LinearLayout>

fragment_clients_list.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView     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:id="@+id/list"
android:name="com.example.app.fragments.ClientsFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
app:layoutManager="LinearLayoutManager"
tools:context=".fragments.ClientsFragment"
tools:listitem="@layout/fragment_clients">

</androidx.recyclerview.widget.RecyclerView>

标签: androidandroid-fragments

解决方案


我找到了解决方案,并进行了小幅调整。现在每个viewHolder都有一个onClickListener,而不是每个项目都有一个按钮,所以当我单击项目(其网格中的任何位置)时,它会打开活动。所做的更改包括:

客户片段

public class ClientsFragment extends Fragment implements MyClientsRecyclerViewAdapter.OnClientListenser {

// TODO: Customize parameter argument names
private static final String ARG_COLUMN_COUNT = "column-count";
// TODO: Customize parameters
private int mColumnCount = 1;

// Vars
private List<DummyContent.DummyItem> mValues = new ArrayList<>();

/**
 * Mandatory empty constructor for the fragment manager to instantiate the
 * fragment (e.g. upon screen orientation changes).
 */
public ClientsFragment() {
}

// TODO: Customize parameter initialization
@SuppressWarnings("unused")
public static ClientsFragment newInstance(int columnCount) {
    ClientsFragment fragment = new ClientsFragment();
    Bundle args = new Bundle();
    args.putInt(ARG_COLUMN_COUNT, columnCount);
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (getArguments() != null) {
        mColumnCount = getArguments().getInt(ARG_COLUMN_COUNT);
    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_client_list, container, false);

    // Set the adapter
    if (view instanceof RecyclerView) {
        Context context = view.getContext();
        RecyclerView recyclerView = (RecyclerView) view;
        if (mColumnCount <= 1) {
            recyclerView.setLayoutManager(new LinearLayoutManager(context));
        } else {
            recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount));
        }
        recyclerView.setAdapter(new MyClientsRecyclerViewAdapter(DummyContent.ITEMS, this));
    }
    return view;
}

@Override
public void onClientClick(int position) {
    Toast.makeText(getActivity(), "Editing Client", Toast.LENGTH_LONG).show();
    Intent intent = new Intent(getActivity(), UpdateClient.class);
    // intent.putExtra("Some info", "something else");
    startActivity(intent);
}
}

MyClientsRecyclerViewAdapter

public class MyClientsRecyclerViewAdapter extends RecyclerView.Adapter<MyClientsRecyclerViewAdapter.ViewHolder> {

private final List<DummyItem> mValues;
private OnClientListenser mOnClientListener;

public MyClientsRecyclerViewAdapter(List<DummyItem> items, OnClientListenser onClientListenser) {
    mValues = items;
    this.mOnClientListener = onClientListenser;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.fragment_clients, parent, false);


    return new ViewHolder(view, mOnClientListener);
}

@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
    holder.mItem = mValues.get(position);
    holder.mIdView.setText(mValues.get(position).id);
    holder.mContentView.setText(mValues.get(position).content);
}

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

public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    public final View mView;
    public final TextView mIdView;
    public final TextView mContentView;
    public DummyItem mItem;

    OnClientListenser onClientListener;

    public ViewHolder(View view, OnClientListenser onClientListener) {
        super(view);
        mView = view;
        mIdView = (TextView) view.findViewById(R.id.item_number);
        mContentView = (TextView) view.findViewById(R.id.content);

        this.onClientListener = onClientListener;
        itemView.setOnClickListener(this);
    }

    @Override
    public String toString() {
        return super.toString() + " '" + mContentView.getText() + "'";
    }

    // Implementation of interface
    @Override
    public void onClick(View v) {
        onClientListener.onClientClick(getAdapterPosition());
    }
}

public interface OnClientListenser{
    public void onClientClick(int position);
}
}

感谢所有在 Facebook 上提供帮助的人,我设法找到了 CodingWithMitch 的这段视频 ( https://www.youtube.com/watch?v=69C1ljfDvl0&feature=emb_logo ),他们帮助我取得了进展!


推荐阅读