Android 动态地将视图膨胀为listView项。古怪的行为
因此,我将根据一个listView项目中需要的视图数量动态创建视图。当用户单击listView项目时,我展开该项目以显示我创建的膨胀视图。我必须这样做的原因是,膨胀视图的数量需要是动态的。可能有2、3甚至5+ 通货膨胀发生得很好,视野开阔得很。问题是当我在listView中滚动时。它似乎将视图膨胀到其他listview项目,而不是用户单击的项目。我知道这是ListView重用其视图以节省内存的预期行为,但在我的代码中这样做有什么原因吗 为了提供一些背景知识,这个类是一个自定义视图,我将它作为RelativeLayout的元素放在另一个xml文件中。setLayout功能应根据需要为尽可能多的视图充气。(这是用于轮询功能) 我的适配器很可能就是问题所在Android 动态地将视图膨胀为listView项。古怪的行为,android,listview,adapter,Android,Listview,Adapter,因此,我将根据一个listView项目中需要的视图数量动态创建视图。当用户单击listView项目时,我展开该项目以显示我创建的膨胀视图。我必须这样做的原因是,膨胀视图的数量需要是动态的。可能有2、3甚至5+ 通货膨胀发生得很好,视野开阔得很。问题是当我在listView中滚动时。它似乎将视图膨胀到其他listview项目,而不是用户单击的项目。我知道这是ListView重用其视图以节省内存的预期行为,但在我的代码中这样做有什么原因吗 为了提供一些背景知识,这个类是一个自定义视图,我将它作为Re
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<>();
}
您应该在listview的方法中应用onClick逻辑,因为它具有
OnItemClickListener
/OnItemSelectedListener
。由于元素是循环使用的,所以onclick可能应用于实际元素,而不是列表的相对项
此处提供了如何使用ListView的完整示例:
但基本思想是扩展OnItemClick方法,该方法接收列表、所选视图(实际使用的视图)和项目id。通过该列表,您可以获取存储的数据和任何相关数据
但是,您应该研究如何使用创建列表。同样的想法也适用,但它在显示列表时更有效,并且为您做了很多工作。我已经尝试了两种方法。它的工作原理是一样的。我正在使用的ListView是一个ListFragment,我已经为它覆盖了onListItemClick。同样的效果。如果用户单击列表中的第一项,则会将视图膨胀到该项中。但是如果你滚动到第五/第六个项目,(回收),那么效果基本上是它将视图膨胀到该项目以及第一个项目中。有时当我向上滚动到顶部时,视图会切换其膨胀的位置。您的类是添加到listView还是父布局?我看到您正在调用父addView。您可能只需要创建一个列表视图,并使用自定义适配器来生成表单和处理加载等。我无法使用适配器的原因是,每个listview项所需的膨胀视图量可能会发生变化。可能是3或10。无法执行listView getItemViewType。我将视图添加到父布局。因此,每个listview项都有一个称为surveyView的不可见视图。然后,当用户单击listview项时,surveyView变为可见。然后膨胀正确数量的视图。在这种情况下,可扩展列表视图不是更好吗?它内置了对扩展的支持,您可以根据需要扩展子条目。我完全忘记了可扩展列表视图。非常感谢。我要试一试。
@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;
}