【问题标题】:RecyclerView duplicates the same object, and I need it to display different onesRecyclerView 复制同一个对象,我需要它来显示不同的对象
【发布时间】:2017-05-18 04:07:15
【问题描述】:

我知道标题可能有点奇怪,但请允许我解释一下!在另一个活动中,我有一个使用 Firebase 和 Recyclerview 显示的对象列表。我能够正确地抓取用户的(我的 OnCreate 中的 Toast 帮助我确定这一点),但是当我尝试将“挑选的”对象显示为新对象(GroupMembers)时,我得到了重复。我认为这是由 mGroupMembers.setName 和 mGroupMembers.setUsername 引起的。我将显示我的适配器的代码,以确保那里没有错误。谁能告诉我为什么会发生这种情况以及为什么它没有正确显示具有相应名称和用户名的所选对象,但 Toast 确实显示了名称和用户名?

这是我的自定义适配器: 成员适配器

public class MembersAdapter extends RecyclerView.Adapter<MembersAdapter.ViewHolder> {
private List<GroupMembers> mMembers;
private final int TOTAL_AMOUNT = 100; //Max amount for all seekbars.
private final List<Integer> mAllProgress = new ArrayList<>();

static class ViewHolder extends RecyclerView.ViewHolder {
    private TextView mName, mUsername, mPercent;
    private SeekBar mSeekBar;

    ViewHolder(View itemView) {
        super(itemView);
        mName = (TextView) itemView.findViewById(R.id.name_view_members);
        mUsername = (TextView) itemView.findViewById(R.id.username_view_members);
        mPercent = (TextView) itemView.findViewById(R.id.percent_text);
        mSeekBar = (SeekBar) itemView.findViewById(R.id.percent_seekbar);
    }
}

//Constructor
public MembersAdapter(List<GroupMembers> members) {
    this.mMembers = members;
}

@Override
public MembersAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout_members, parent, false);
    return new ViewHolder(v);
}

@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
    GroupMembers individual = mMembers.get(position);
    holder.mName.setText(individual.getName());
    holder.mUsername.setText(individual.getUsername());

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

这里是 OnCreate 方法,我刚刚包括了我从其他活动中获取额外内容的地方,直到使用适配器和 recyclerview 的地方。

这是我的相关活动: PaymentsOptionActivity

public class PaymentOptionsActivity extends AppCompatActivity {

//Tag
private static String TAG = "PaymentOptionsActivity";

@Bind(R.id.name_label)
TextView mNameLabel;
@Bind(R.id.cost_label)
TextView mCostLabel;
@Bind(R.id.color_label)
TextView mColorLabel;
@Bind(R.id.recurrence_label)
TextView mRecurrenceLabel;
@Bind(R.id.name_field)
EditText mNameField;
@Bind(R.id.cost_field)
EditText mCostField;
@Bind(R.id.color_button)
Button mColorButton;
@Bind(R.id.recurrence_spinner)
Spinner mRecurrenceSpinner;
@Bind(R.id.activity_payment_options)
RelativeLayout mActivityPaymentOptions;
@Bind(R.id.members_recycler)
RecyclerView mRecyclerview;
@Bind(R.id.bottom_naviation)
BottomNavigationView mBottomNavigationView;

private int mSelectedColor;
private List<GroupMembers> mMembers = new ArrayList<>(); //Group Members in a List.
private GroupMembers mGroupMembers = new GroupMembers(); //Individual Group Members
private MembersAdapter mAdapter;
private String name;
private String email;
private String username;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_payment_options);
    ButterKnife.bind(this);
    initiateBottomView();

    //Extra from other activity.
    List<UserList> groupMembers = (List<UserList>) getIntent().getSerializableExtra("users"); //Selected Members

    //Convert UserList -> Members
    for (UserList users : groupMembers) {
        name = users.getName();
        email = users.getEmail();
        username = users.getUsername();

        mGroupMembers.setName(name);
        mGroupMembers.setUsername(username);

        //Display who's picked for testing.
        Toast.makeText(this, "Selected:  " + name, Toast.LENGTH_SHORT).show();

        //List<GroupMembers> now has however members were selected..
        mMembers.add(mGroupMembers);

    //RecyclerView + Adapter
    mRecyclerview.setHasFixedSize(true);
    mRecyclerview.setLayoutManager(new LinearLayoutManager(this));
    mAdapter = new MembersAdapter(mMembers);
    mRecyclerview.setAdapter(mAdapter);
    }
    public void initiateBottomView() {
    mBottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            Intent i;
            switch (item.getItemId()) {
                case R.id.action_groups:
                    //Refresh
                    i = new Intent(PaymentOptionsActivity.this, PaymentsSearchActivity.class);
                    startActivity(i);
                    return true;
                case R.id.action_dashboard:
                    i = new Intent(PaymentOptionsActivity.this, DashboardActivity.class);
                    startActivity(i);
                    return true;
                case R.id.action_profile:
                    item.setEnabled(true);
                    i = new Intent(PaymentOptionsActivity.this, ProfileActivity.class);
                    startActivity(i);
                    return true;
            }
            return false;
        }
    });
}

任何帮助都将不胜感激,如果我应该对我的代码提出任何建议,我也将不胜感激。这是一个相当大的应用程序,这就是为什么我排除了这么多代码以保持它的相关性。

非常感谢!

【问题讨论】:

  • 为了澄清一下,如果有人好奇......当测试在 OnCreate 方法中选择的用户时,我尝试Toast.makeText(this, "Selected: " + mGroupMembers.getName(), Toast.LENGTH_SHORT).show(); 来测试 GroupMembers 是否实际上设置了两个名称,它是!很困惑,我知道这必须是一个简单的解决方法。

标签: android arraylist android-recyclerview android-adapter


【解决方案1】:

你的问题在这里:

mGroupMembers.setName(name);
mGroupMembers.setUsername(username);

mGroupMembers 是一个被多次添加到列表中的对象,因此您的列表包含完全相同的对象的集合,我想在RecyclerView 中一遍又一遍地显示最后一个条目。

您不应该将 mGroupMembers 作为实例变量,将其删除并改为:

    for (UserList users : groupMembers) {
            name = users.getName();
            email = users.getEmail();
            username = users.getUsername();

            GroupMembers groupMembers = new GroupMembers();
            groupMembers.setName(name);
            groupMembers.setUsername(username);

            //Display who's picked for testing.
            Toast.makeText(this, "Selected:  " + name, Toast.LENGTH_SHORT).show();

            //List<GroupMembers> now has however members were selected..
            mMembers.add(groupMembers);
}

或者类似的东西,所以你创建一个单独的 GroupMembers 列表,而不是一个引用同一个 GroupMembers 对象的列表。

【讨论】:

  • 是的!这解决了我的问题。这很有意义......出于某种奇怪的原因,我认为它会迭代,将对象添加到列表中,然后重置以添加新对象,但我没有意识到它实际上在做什么。非常感谢。
  • 没问题,有时你必须小心设置器,因为它确实将你的对象暴露给可变性。如果您在创建后永远不会更改对象,请删除设置器并为除其参数/参数之外的类创建一个构造函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-11
  • 2013-05-10
  • 1970-01-01
  • 2020-05-17
  • 2014-11-18
相关资源
最近更新 更多