在自定义 Adapter 中遍历 ListView
Iterate through ListView in custom Adapter
我有一个习惯ListView
。每行包含一个 TextView
和 ImageView
.
看截图:
在项目上单击我使 ImageView
可见。但问题是一次只能看到一个 ImageView
。
我认为最好的方法是在单击时将所有其他 ImageViews
设置为 INVISIBLE
。在所有图像消失后,点击一个 VISIBLE
。
但我不知道如何正确迭代 Adapter
:
private class TimeZoneItemAdapter extends ArrayAdapter<String> {
private Activity myContext;
private ArrayList<String> datas;
public TimeZoneItemAdapter(Context context, int textViewResourceId, ArrayList<String> objects) {
super(context, textViewResourceId, objects);
myContext = (Activity) context;
datas = objects;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder;
if (convertView == null) {
LayoutInflater inflater = myContext.getLayoutInflater();
convertView = inflater.inflate(R.layout.listview_item, null);
viewHolder = new ViewHolder();
viewHolder.postNameView = (TextView) convertView.findViewById(R.id.listview_item);
viewHolder.postImageView = (ImageView) convertView.findViewById(R.id.image_mark);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.postNameView.setText(datas.get(position));
viewHolder.postNameView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//clear all image views during iteration
View view;
for (int i = 0; i < datas.size(); i++) {
//dont know which parameter need there for proper iteration
view = getView(i, ?????, null);
ImageView image = (ImageView) view.findViewById(R.id.image_mark);
image.setVisibility(View.INVISIBLE);
}
if (viewHolder.postImageView.getVisibility() != View.VISIBLE) {
selectedTimeZone = viewHolder.postNameView.getText().toString();
viewHolder.postImageView.setVisibility(View.VISIBLE);
} else {
viewHolder.postImageView.setVisibility(View.INVISIBLE);
}
}
});
return convertView;
}
class ViewHolder {
TextView postNameView;
ImageView postImageView;
}
}
请帮助我或给些提示。我已经很困惑了。
只有一种解决方案:
private static View lastClicked = null;
... ...
viewHolder.postNameView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
View parentRow = (View) v.getParent();
ViewHolder viewHolder = (ViewHolder)parentRow.getTag();
if(viewHolder.postImageView.getVisibility() != View.VISIBLE)
{
//clear last clicked image
if(lastClicked != null)
{
ViewHolder lastHolder = (ViewHolder)lastClicked.getTag();
lastHolder.postImageView.setVisibility(View.INVISIBLE);
}
selectedTimeZone = viewHolder.postNameView.getText().toString();
viewHolder.postImageView.setVisibility(View.VISIBLE);
lastClicked = parentRow;
}
else
{
viewHolder.postImageView.setVisibility(View.INVISIBLE);
lastClicked = null;
}
});
希望对您有所帮助!
我不会存储有关视图的任何信息。我相信 listview 会回收它的视图,所以事情会变得一团糟。尝试将数据与视图分开。
我会尝试不同的方法。您的 datas
应该是
ArrayList<MyData> datas;
public class MyData{
String place;
boolean: checked = false;
}
要填充 datas
ArrayList,您可以这样做
for (String s : objects){
MyData d = new MyData();
d.place = s;
}
然后在你的适配器中 getView
你应该 display/hide 基于 checked
值的 imageView 像这样:
private class TimeZoneItemAdapter extends ArrayAdapter<MyData> {
private Activity myContext;
private ArrayList<MyData> datas;
public TimeZoneItemAdapter(Context context, int textViewResourceId, ArrayList<MyDatas> datas) {
super(context, textViewResourceId, datas);
this.datas = datas;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = myContext.getLayoutInflater();
convertView = inflater.inflate(R.layout.listview_item, null);
}
TextView postNameView = (TextView) convertView.findViewById(R.id.listview_item);
TextView postImageView = (ImageView) convertView.findViewById(R.id.image_mark);
postNameView.setText(this.datas.get(position).place);
if(this.datas.get(position).checked){
postImageView.setVisibility(View.VISIBLE);
}else{
postImageView.setVisibility(View.INVISIBLE);
}
return convertView;
}
}
单击某个项目时,您应该重复 datas
,取消选中所有内容并选中相应的项目。然后更新你调用的 listView
((TimeZoneItemAdapter)list.getAdapter()).notifyDataSetChanged();
并且所有的视图都会自动更新。
在 onClick 中,您将遍历视图并确保它们都隐藏了图像,然后将当前图像设置为可见。您不需要自己做,只需告诉系统为您做即可。
另请注意,您当前的代码将循环适配器中的所有条目并尝试获取它们的视图...但并非所有条目都有一个,滚动到屏幕外的那些将没有查看。
最简单的方法是从您的 onClick 处理程序中删除除您设置 selectedTimeZone
的行之外的所有内容,然后调用 notifyDataSetChanged()
。这将使 Android 重绘所有当前屏幕上的视图。
然后在您的 setText()
下方添加:
if (datas.get(position).equals(selectedTimeZone)) {
viewHolder.postImageView.setVisibility(View.VISIBLE);
} else {
viewHolder.postImageView.setVisibility(View.INVISIBLE);
}
因此,当系统重新绘制视图时,将考虑将每个视图的图像设置为可见,但只有当前视图才会设置它。
我有一个习惯ListView
。每行包含一个 TextView
和 ImageView
.
看截图:
在项目上单击我使 ImageView
可见。但问题是一次只能看到一个 ImageView
。
我认为最好的方法是在单击时将所有其他 ImageViews
设置为 INVISIBLE
。在所有图像消失后,点击一个 VISIBLE
。
但我不知道如何正确迭代 Adapter
:
private class TimeZoneItemAdapter extends ArrayAdapter<String> {
private Activity myContext;
private ArrayList<String> datas;
public TimeZoneItemAdapter(Context context, int textViewResourceId, ArrayList<String> objects) {
super(context, textViewResourceId, objects);
myContext = (Activity) context;
datas = objects;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder;
if (convertView == null) {
LayoutInflater inflater = myContext.getLayoutInflater();
convertView = inflater.inflate(R.layout.listview_item, null);
viewHolder = new ViewHolder();
viewHolder.postNameView = (TextView) convertView.findViewById(R.id.listview_item);
viewHolder.postImageView = (ImageView) convertView.findViewById(R.id.image_mark);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.postNameView.setText(datas.get(position));
viewHolder.postNameView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//clear all image views during iteration
View view;
for (int i = 0; i < datas.size(); i++) {
//dont know which parameter need there for proper iteration
view = getView(i, ?????, null);
ImageView image = (ImageView) view.findViewById(R.id.image_mark);
image.setVisibility(View.INVISIBLE);
}
if (viewHolder.postImageView.getVisibility() != View.VISIBLE) {
selectedTimeZone = viewHolder.postNameView.getText().toString();
viewHolder.postImageView.setVisibility(View.VISIBLE);
} else {
viewHolder.postImageView.setVisibility(View.INVISIBLE);
}
}
});
return convertView;
}
class ViewHolder {
TextView postNameView;
ImageView postImageView;
}
}
请帮助我或给些提示。我已经很困惑了。
只有一种解决方案:
private static View lastClicked = null;
... ...
viewHolder.postNameView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
View parentRow = (View) v.getParent();
ViewHolder viewHolder = (ViewHolder)parentRow.getTag();
if(viewHolder.postImageView.getVisibility() != View.VISIBLE)
{
//clear last clicked image
if(lastClicked != null)
{
ViewHolder lastHolder = (ViewHolder)lastClicked.getTag();
lastHolder.postImageView.setVisibility(View.INVISIBLE);
}
selectedTimeZone = viewHolder.postNameView.getText().toString();
viewHolder.postImageView.setVisibility(View.VISIBLE);
lastClicked = parentRow;
}
else
{
viewHolder.postImageView.setVisibility(View.INVISIBLE);
lastClicked = null;
}
});
希望对您有所帮助!
我不会存储有关视图的任何信息。我相信 listview 会回收它的视图,所以事情会变得一团糟。尝试将数据与视图分开。
我会尝试不同的方法。您的 datas
应该是
ArrayList<MyData> datas;
public class MyData{
String place;
boolean: checked = false;
}
要填充 datas
ArrayList,您可以这样做
for (String s : objects){
MyData d = new MyData();
d.place = s;
}
然后在你的适配器中 getView
你应该 display/hide 基于 checked
值的 imageView 像这样:
private class TimeZoneItemAdapter extends ArrayAdapter<MyData> {
private Activity myContext;
private ArrayList<MyData> datas;
public TimeZoneItemAdapter(Context context, int textViewResourceId, ArrayList<MyDatas> datas) {
super(context, textViewResourceId, datas);
this.datas = datas;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = myContext.getLayoutInflater();
convertView = inflater.inflate(R.layout.listview_item, null);
}
TextView postNameView = (TextView) convertView.findViewById(R.id.listview_item);
TextView postImageView = (ImageView) convertView.findViewById(R.id.image_mark);
postNameView.setText(this.datas.get(position).place);
if(this.datas.get(position).checked){
postImageView.setVisibility(View.VISIBLE);
}else{
postImageView.setVisibility(View.INVISIBLE);
}
return convertView;
}
}
单击某个项目时,您应该重复 datas
,取消选中所有内容并选中相应的项目。然后更新你调用的 listView
((TimeZoneItemAdapter)list.getAdapter()).notifyDataSetChanged();
并且所有的视图都会自动更新。
在 onClick 中,您将遍历视图并确保它们都隐藏了图像,然后将当前图像设置为可见。您不需要自己做,只需告诉系统为您做即可。
另请注意,您当前的代码将循环适配器中的所有条目并尝试获取它们的视图...但并非所有条目都有一个,滚动到屏幕外的那些将没有查看。
最简单的方法是从您的 onClick 处理程序中删除除您设置 selectedTimeZone
的行之外的所有内容,然后调用 notifyDataSetChanged()
。这将使 Android 重绘所有当前屏幕上的视图。
然后在您的 setText()
下方添加:
if (datas.get(position).equals(selectedTimeZone)) {
viewHolder.postImageView.setVisibility(View.VISIBLE);
} else {
viewHolder.postImageView.setVisibility(View.INVISIBLE);
}
因此,当系统重新绘制视图时,将考虑将每个视图的图像设置为可见,但只有当前视图才会设置它。