动态地将视图扩展到listView项目。奇怪的行为

时间:2015-06-08 20:28:06

标签: android listview adapter

所以我根据listView项目需要的数量动态创建视图。当用户单击listView项时,我展开项目以显示我所做的膨胀视图。我必须这样做的原因是因为膨胀的视图量需要是动态的。可能有2,3或甚至5 +。

通货膨胀很好,观点扩大了很多。问题是当我在listView中滚动时。它似乎将视图扩展到其他listview项而不是用户单击的项。我知道这是预期的行为,因为listViews重用它们的视图来节省内存,但是它有什么理由在我的代码中这样做吗?

为了给出一些背景故事,这个类是一个自定义视图,我将其放在另一个xml文件中作为RelativeLayout的元素。 setLayout函数应根据需要扩展尽可能多的视图。 (这是用于轮询功能) 我的适配器很可能是问题所在。

public class SurveyView extends LinearLayout {
private LinearLayout pollContainer;
private Context context;
private String type;
private int numOfAnswers;
private ListView answersList;
private ArrayList<String> answers;
private boolean visibility = true;
private OnClickListener listener;
private ArrayList<View> options;
private int tag = 888888888;

/**
 *
 * @param context the context of the activity
 * @param type the type of poll
 * @param numOfAnswers if the poll is multiple choice (most likely) provide number of answers.
 */
public void setLayout(Context context, String type, int numOfAnswers) {
    this.type = type;
    this.numOfAnswers = numOfAnswers;
    this.context = context;

    switch (type) {
        case "Multiple":
            if (visibility) {
                for (int i = 0; i < numOfAnswers; i++) {
                    View v = LayoutInflater.from(getContext()).inflate(R.layout.poll_multiple_choice_answers_row, null);
                    v.setTag(tag);
                    tag++;
                    v.setOnClickListener(new OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            Toast.makeText(getContext(), v.getTag().toString(), Toast.LENGTH_SHORT).show();
                            RadioButton rb = (RadioButton)v.findViewById(R.id.answer_voted_button);
                            rb.setChecked(true);
                        }
                    });
                    addView(v);
                    options.add(v);
                }
            }
            break;
        case "Slider":
            break;
        case "Tree":
            break;
        case "Sentiment":
            break;
    }
}

public SurveyView(Context context, AttributeSet attrs) {
    super(context, attrs);
    setOrientation(VERTICAL);
    options = new ArrayList<>();
}

这是我的适配器代码。

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    final ViewHolder viewHolder;
    if (convertView == null) {
        viewHolder = new ViewHolder();
        convertView = inflater.inflate(R.layout.polls_card_layout, null);
        viewHolder.type = (TextView)convertView.findViewById(R.id.card_type);
        viewHolder.time = (TextView)convertView.findViewById(R.id.card_poll_time);
        viewHolder.text = (TextView)convertView.findViewById(R.id.card_text);
        viewHolder.space = (TextView)convertView.findViewById(R.id.card_space);
        viewHolder.pollSpace = (TextView)convertView.findViewById(R.id.poll_space);
        viewHolder.type_icon = (ImageView)convertView.findViewById(R.id.card_icon);
        viewHolder.answerView = (SurveyView)convertView.findViewById(R.id.poll_component);
        convertView.setTag(viewHolder);
    }
    else {
        viewHolder = (ViewHolder)convertView.getTag();
    }

    viewHolder.type.setText(data.get(position).getType());
    viewHolder.time.setText(data.get(position).getTime());
    viewHolder.text.setText(data.get(position).getText());

    convertView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (viewHolder.getAnswerView().getHeight() == 0) {
                viewHolder.answerView.setLayout(context, "Multiple", 5);
                RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
                params.addRule(RelativeLayout.BELOW, R.id.poll_space);
                params.addRule(RelativeLayout.RIGHT_OF, R.id.card_icon);
                viewHolder.answerView.setLayoutParams(params);
            } else {
                viewHolder.getAnswerView().setVisibility(false);
                RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, 0);
                params.addRule(RelativeLayout.BELOW, R.id.poll_space);
                params.addRule(RelativeLayout.RIGHT_OF, R.id.card_icon);
                viewHolder.answerView.setLayoutParams(params);
            }
        }
    });
    return convertView;
}

1 个答案:

答案 0 :(得分:0)

您应该在listview的方法中应用onClick逻辑,因为它具有OnItemClickListener / OnItemSelectedListener。由于元素被回收,因此onclick可能会应用于实际元素而不是列表中的相关项。

此处提供了有关如何使用ListView的完整示例: https://developer.android.com/guide/topics/ui/layout/listview.html

但基本思路是扩展OnItemClick方法,该方法接收列表,查看所选(实际使用中的视图)和项目的ID。使用该列表,您可以获取存储的数据和任何相关数据。

但是,您应该考虑使用RecyclerView来创建列表。同样的想法适用,但它更有效地显示列表,并为您做了很多工作。