我有一个自定义baseadapter,它会对某些图像进行一些延迟加载,然后对布局进行充气,以便最终得到一个listview,其中我将图像和文本放在一行中。
当用户按下列表视图中的一个项目时,例如项目0(顶部项目),我想显示一个包含特定内容的对话框。此内容取决于项目编号 - 因此项目0显示的内容与项目1不同,依此类推。
以下是自定义适配器的getView
方法:
public View getView(int position, View convertView, ViewGroup parent)
{
View vi=convertView;
if(convertView==null)
{
vi = inflater.inflate(R.layout.facebook_item, null);
vi.setClickable(true);
vi.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
String s = "test";
Toast.makeText(myContext, s, Toast.LENGTH_SHORT).show();
}
});
}
TextView text=(TextView)vi.findViewById(R.id.text);
ImageView image=(ImageView)vi.findViewById(R.id.image);
text.setText(msg[position]);
text.getLineCount();
imageLoader.DisplayImage(data[position], image);
return vi;
}
这里重要的是onClick
方法中发生了什么。我想有一个item参数,但这对于这个OnClickListener是不可能的。正常的列表视图是可能的,我知道。
那么 - 如何确定点击了哪个项目?
PS:我试图考虑使用某种vi.setTag(<<number>>);
,但如果没有为列表视图的所有项目设置相同的标记,我不知道如何做到这一点。
答案 0 :(得分:5)
为什么不在ListView本身上使用onItemClickListener?
您的适配器应包含一个对象类型的列表(没有严格的规则,但它有助于更轻松地管理项目)。例如
class MsgObject{
String msg;
String data
//TODO Getters/Setters goes here
}
然后您的CustomAdapter将只包含
List<MsgObject> objectList;
然后你的getView看起来与此类似
MsgObject m = (MsgObject)getObject(position);
TextView text=(TextView)vi.findViewById(R.id.text);
ImageView image=(ImageView)vi.findViewById(R.id.image);
text.setText(m.getMsg());
text.getLineCount();
imageLoader.DisplayImage(m.getData(), image);
//Tag id is predefined in xml
vi.setTag(R.id.listItemTag, m);
return vi;
现在,您的视图将把它作为一个对象处理,而不是一个具有多个值的布局。
然后我们将所有点击操作移动到ListView所在的Activity。
listView.setOnItemClickListener(){
new AdapterView.OnItemClickListener(){
@override
public onItemClick(AdapterView<?> parent, View view, int position, long id){
MsgObject m = (MsgObject)view.getTag(R.id.listItemTag);
Toast.makeText(context, "Pos[" + position
+ "] clicked, with msg: " + m.getMessage(), Toast.LENGTH_SHORT).show();
}
}
};
这是我使用Lazy加载ImageView的ListView的方式。然后,您将能够访问与该视图关联的对象以及单击的位置。
如果您希望将msg和数据分开。你可以使用setTag(id,obj);对于对象等等。
setTag(R.id.listItemMsg, msg[position]);
setTag(R.id.listItemData, data[position]);
更新:我的CustomAdapter示例
/**
* Adapter for displaying Place selection list.
* @author Poohdish Rattanavijai
*
*/
public class PlaceAdapter extends BaseAdapter {
private static final String TAG = PlaceAdapter.class.getSimpleName();
private List<PlaceVO> list; // <-- list of PlaceVOs
private Context context;
private int viewResourceId;
/**
*
* @param context Context
* @param viewResourceId Layout ID for each item
* @param list resource list to populate
*/
public PlaceAdapter(Context context, int viewResourceId, List<PlaceVO> list){
this.context = context;
this.viewResourceId = viewResourceId;
this.list = list;
}
/**
* Number of result in the list plus one (for +add at the last item)
*/
@Override
public int getCount() {
if(null != list){
return list.size();
}
return 1;
}
@Override
public Object getItem(int arg0) {
if(null != list){
try {
return list.get(arg0);
} catch (IndexOutOfBoundsException e) {
return null;
}
}
return null;
}
@Override
public long getItemId(int position) {
// if(null != list){
// try {
// return list.get(position).getId();
// } catch (IndexOutOfBoundsException e) {
// return 0;
// }
// }
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(null == convertView){
/**
* View does not exist, populate.
*/
LayoutInflater inflater = LayoutInflater.from(this.context);
convertView = inflater.inflate(this.viewResourceId, parent, false);
}
ViewHolder holder = (ViewHolder)convertView.getTag(R.id.adpter_view);
if(null == holder){
Log.d(TAG, "holder not found, init.");
/**
* ViewHolder does not exists for this view; create and assign respective view.
*/
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.title);
holder.details = (TextView) convertView.findViewById(R.id.details);
holder.icon = (ImageView) convertView.findViewById(R.id.icon);
holder.progress = (ProgressBar) convertView.findViewById(R.id.progress);
}
PlaceVO v = (PlaceVO)getItem(position); // <-- GetItem
if(null != v){
Log.d(TAG, "Place not null");
if(HelperUtil.IsNotNullOrEmpty(v.getName())){
Log.d(TAG, "Name: " + v.getName());
holder.title.setText(v.getName());
}
if(HelperUtil.IsNotNullOrEmpty(v.getVicinity())){
Log.d(TAG, "details: " + v.getVicinity());
holder.details.setText(v.getVicinity());
}
if(HelperUtil.IsNotNullOrEmpty(v.getIcon())){
holder.progress.setVisibility(View.VISIBLE);
holder.icon.setVisibility(View.GONE);
//TODO Initialize LazyLoad
}else{
holder.progress.setVisibility(View.VISIBLE);
holder.icon.setVisibility(View.GONE);
}
}
// Two tags, one for holder, another for the VO
convertView.setTag(R.id.adpter_view, holder);
convertView.setTag(R.id.adpter_object, v);
return convertView;
}
static class ViewHolder{
TextView title;
TextView details;
ImageView icon;
ProgressBar progress;
}
}
内部活动我使用
处理项目点击操作OnItemClickListener itemClick = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
PlaceVO v = (PlaceVO)arg1.getTag(R.id.adpter_object); // <-- get object using tag.
switchToPlaceScreen(v);
}
};
listView.setOnItemClickListener(itemClick);
希望这能回答你的问题:)
答案 1 :(得分:1)
text.setText(msg[position]);
text.getLineCount();
imageLoader.DisplayImage(data[position], image);
在创建自定义适配器时,您希望尽可能使用getItem(int position)引用项目。避免使用您在Adapter构造函数中传递的实际数组来引用它。
尝试覆盖适配器上的getItem(int position)
和getItemId(int position)
,并在getView
内使用它代替数组。