动态地向CardView添加视图而不重复

时间:2017-07-06 14:06:36

标签: android android-recyclerview android-cardview

我有CardView的布局,最初有2个TextView和2个按钮。根据{{​​1}}中的#options,poll.getOptions()最多可以有5个按钮。所以我想动态添加这些按钮...如果我在Cardview中添加它们,在单击按钮后,它会添加这些按钮的重复项。我尝试在onBindViewHolder中添加它,但是当我尝试创建一个新按钮时,它会给我一个onCreateViewHolder。我试过很多方法,但无法找到解决方案。在NullPointerException中添加动态视图的真正方法是什么?为什么它会给我这个错误?

cardview的布局:

CardView

我的<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto"> <data> <variable name = "poll" type = "mattoncino.pollo.Poll" /> </data> <android.support.v7.widget.CardView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" card_view:cardCornerRadius="@dimen/cardview_default_radius" card_view:cardElevation="@dimen/cardview_default_elevation"> <LinearLayout android:id="@+id/listItemLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="5dp"> <TextView android:id="@+id/nameTextView" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="30sp" android:textAllCaps="false" android:text="@{poll.name}"/> <TextView android:id="@+id/questionTextView" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="20sp" android:text="@{poll.question}"/> <Button android:id="@+id/opt1Button" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="18sp" android:textAllCaps="false" android:text="@{poll.getText(1)}" android:enabled="@{!poll.disabled}"/> <Button android:id="@+id/opt2Button" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:textSize="18sp" android:textAllCaps="false" android:text="@{poll.getText(2)}" android:enabled="@{!poll.disabled}"/> </LinearLayout> </android.support.v7.widget.CardView> </layout> 课程:

CardViewAdapter

我在public class PollsCardViewAdapter extends RecyclerView.Adapter<PollsCardViewAdapter.CardViewHolder> { private List<Poll> activePolls; private final static String TAG = "CARDVIEW_ADAPTER"; public PollsCardViewAdapter(List<Poll> polls){ activePolls = polls; } public static class CardViewHolder extends RecyclerView.ViewHolder { private ActivePollsListItemBinding listItemBinding; public CardViewHolder(View v) { super(v); listItemBinding = DataBindingUtil.bind(v); } public ActivePollsListItemBinding getBinding(){ return listItemBinding; } } // Create new views (invoked by the layout manager) @Override public PollsCardViewAdapter.CardViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.active_polls_list_item, parent, false); CardViewHolder holder = new CardViewHolder(v); Context context = holder.getBinding().nameTextView.getContext(); Poll poll = activePolls.get(viewType); for (int i = 2; i < poll.getOptions().size(); i++) { int opt = i + 1; Button button = createNewOptionButton(context, poll.getText(opt)); if(poll.isDisabled()) { button.setEnabled(false); } else button.setText(poll.getText(opt)); parent.addView(button); } return holder; } // Replace the contents of a view (invoked by the layout manager) @Override public void onBindViewHolder(final PollsCardViewAdapter.CardViewHolder holder, final int position) { final Poll poll = activePolls.get(position); final LinearLayout rLayout = holder.getBinding().listItemLayout; if(!poll.isDisabled()){ for (int i = 2; i < rLayout.getChildCount(); i++){ final View view = rLayout.getChildAt(i); final int opt = i - 1; if(view instanceof Button){ final Button button = (Button) view; button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { button.setText(button.getText().toString() + " " + "\u2713"); setCardDetails(holder.getBinding().nameTextView.getContext(), rLayout, poll, opt); } }); } } } holder.getBinding().setVariable(BR.poll, poll); holder.getBinding().executePendingBindings(); } private void setCardDetails(final Context context, final LinearLayout rLayout, final Poll poll, final int opt){ poll.setDisabled(true); disableOptionButtons(rLayout); rLayout.addView(addMessageView(context)); Handler handler = new Handler(); final Runnable r = new Runnable(){ @Override public void run() { poll.addVote(opt); notifyDataSetChanged(); } }; handler.post(r); } private void disableOptionButtons(ViewGroup layout){ for (int i = 0; i < layout.getChildCount(); i++) { View child = layout.getChildAt(i); if(child.hasOnClickListeners()) child.setEnabled(false); } } private TextView addMessageView(Context context){ LinearLayout.LayoutParams lparams = new LinearLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT); TextView textView = new TextView(context); textView.setLayoutParams(lparams); textView.setId(View.generateViewId()); textView.setText("Thanks for voting! Wait for results..."); textView.setTextSize(20); textView.setTypeface(null, Typeface.BOLD_ITALIC); return textView; } private static Button createNewOptionButton(Context context, String option) { LinearLayout.LayoutParams lparams = new LinearLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT); final Button button = new Button(context); button.setLayoutParams(lparams); button.setId(View.generateViewId()); button.setTextSize(18); button.setText(option); //button.setBackgroundColor(Color.TRANSPARENT); return button; } @Override public int getItemCount() { return activePolls.size(); } }

中获得的例外情况
createNewOptionButton()

2 个答案:

答案 0 :(得分:0)

我认为最安全的选择是在布局xml中添加所有5个按钮,并将它们与

一起使用
android:visibility="gone"

所以他们没有出现。

然后在onBindViewHolder中,您可以使用View.setVisibility()

检查所需按钮的数量,并相应地修改可见性

示例代码:

@Override
public void onBindViewHolder(final PollsCardViewAdapter.CardViewHolder holder, final int position) {
    ...

    int numOfButtons = poll.getOptions().size();
    for (int i = 0; i < 5; i++) {
        Button b = holder.buttons[i];
        if (i < numOfButtons) {
            b.setVisibility(View.VISIBLE);
            // configure button's text and whatever
        } else {
            b.setVisibility(View.GONE);
        }
    }

    ...
}

答案 1 :(得分:0)

您可以动态添加按钮。

使用onclicklistener和onclicklistener的onclick方法设置poll选项..

创建5个新按钮并将其添加到cardView。

Button btn1 = new Button(context);
BUtton btn2 = new Button(context);
Button btn3 = new Button(context);

cardView.addView (btn1);

重复此操作。

获取特定项目的cardView ..

在viewHolder中定义onclicklistener并使用getAdapterPosition()方法获取位置。

通过这种方式你可以添加它