Onclicklistener 在片段列表视图中不起作用
Posted
技术标签:
【中文标题】Onclicklistener 在片段列表视图中不起作用【英文标题】:Onclicklistner not working in fragment listview 【发布时间】:2013-02-13 08:54:10 【问题描述】:我在 listfragment 中有一个带有自定义适配器的 listview,并且还为 listview 设置了 onclicklistner。但是 Onclicklistner 不起作用。
这是我的代码:
public class BasicFragment extends ListFragment
ListView lv;
MyCustomAdapter adapter;
@Override
public void onCreate(Bundle si)
super.onCreate(si);
@Override
public void onActivityCreated(Bundle b)
super.onActivityCreated(b);
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
View view = inflater.inflate(R.layout.fragment_basic, container, false);
lv = (ListView) view.findViewById(android.R.id.list);
FetchedData DT = FetchedData.StaticDataTransfer();
RecepiesProperties[] AryObjaz = DT.getData();
getdata(AryObjaz);
adapter = new MyCustomAdapter(getActivity(), R.layout.listview_layout,
Dataset);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3)
Toast t = Toast.makeText(getActivity(), "Message",
Toast.LENGTH_SHORT);
t.show();
);
return view;
MyCustomAdapter.java
public class MyCustomAdapter extends ArrayAdapter<Recipes>
Context context;
int layoutResourceId;
Recipes data[] = null;
Typeface typeface;
public ImageLoader imageLoader;
public MyCustomAdapter(Context context, int textViewResourceId,
Recipes[] dataset)
super(context, textViewResourceId, dataset);
this.layoutResourceId = textViewResourceId;
this.context = context;
this.data = dataset;
imageLoader = new ImageLoader(context.getApplicationContext());
@Override
public View getView(int position, View convertView, ViewGroup parent)
View row = convertView;
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
RecipesHolder holder = new RecipesHolder();
holder.imgIcon = (ImageView) row.findViewById(R.id.imageView1);
holder.txtTitle = (TextView) row.findViewById(R.id.title);
holder.category = (TextView) row.findViewById(R.id.category);
holder.source = (TextView) row.findViewById(R.id.source);
holder.country = (TextView) row.findViewById(R.id.country);
holder.readytime = (TextView) row.findViewById(R.id.readytime);
holder.tips = (Button) row.findViewById(R.id.tips);
holder.fav = (Button) row.findViewById(R.id.fav);
Recipes ap = data[position];
imageLoader.DisplayImage(ap.getIMAGENAME240(), holder.imgIcon);
holder.txtTitle.setText(ap.getNAME());
holder.category.setText(ap.getCATEGORY());
holder.source.setText(ap.getSOURCE());
holder.country.setText(ap.getCOUNTRY());
holder.readytime.setText(ap.getREADYTIME());
return row;
static class RecipesHolder
ImageView imgIcon;
TextView txtTitle;
TextView category;
TextView source;
TextView country;
TextView readytime;
Button tips;
Button fav;
//listview_layout.xml
<RelativeLayout
android:layout_
android:layout_><ImageView
android:id="@+id/imageView1"
android:layout_
android:layout_
android:layout_alignParentLeft="true"
android:focusable="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="5dp"
android:layout_marginTop="10dp" />
<TextView
android:id="@+id/readytime"
android:layout_
android:layout_
android:layout_alignBaseline="@+id/country"
android:layout_alignBottom="@+id/country"
android:layout_marginLeft="73dp"
android:layout_toRightOf="@+id/country"
android:focusable="true"
android:text="TextView"
android:textColor="#000" />
<TextView
android:id="@+id/country"
android:layout_
android:layout_
android:layout_alignBottom="@+id/imageView1"
android:layout_alignLeft="@+id/source"
android:focusable="true"
android:text="TextView"
android:textColor="#000" />
<TextView
android:id="@+id/source"
android:layout_
android:layout_
android:layout_above="@+id/country"
android:layout_alignLeft="@+id/category"
android:focusable="true"
android:text="TextView"
android:textColor="#000" />
<TextView
android:id="@+id/category"
android:layout_
android:layout_
android:layout_above="@+id/source"
android:layout_alignLeft="@+id/title"
android:text="TextView"
android:focusable="true"
android:textColor="#000" />
<TextView
android:id="@+id/title"
android:layout_
android:layout_
android:layout_above="@+id/category"
android:layout_toRightOf="@+id/imageView1"
android:text="TextView"
android:focusable="true"
android:textColor="#000" />
<Button
android:id="@+id/fav"
android:layout_
android:layout_
android:layout_alignLeft="@+id/tips"
android:layout_below="@+id/source"
android:focusable="true"
android:background="@drawable/favourite" />
<Button
android:id="@+id/tips"
android:layout_
android:layout_
android:layout_alignParentRight="true"
android:layout_alignTop="@+id/textView1"
android:layout_marginRight="14dp"
android:background="@drawable/yellow" /></RelativeLayout>
【问题讨论】:
您是否尝试在 onViewCreated(View view, Bundle savedInstanceState) 中声明监听器?而不是在 onCreateView() 内部。它不应该存在于 onViewCreate() 方法中。 【参考方案1】:终于解决了listview中所有控件(Buttons,textviews)设置为focusable false时的问题。
【讨论】:
谢谢!经过一个小时的调试,这对我有所帮助......! 这对我也有用!我将代码 android:focusable="false" 用于与我的片段类关联的 XML 中的所有 Buttons 和 TextViews。跨度> 【参考方案2】:检查您的 MyCustomAdapter,自定义布局中的某些小部件(例如:Button、ImageButton)会消耗点击事件,然后永远不会调用 onItemClick。
在您的 adaper 的 getView 方法中使用以下代码来获取 onClick 事件。
row.setOnClickListener(new OnClickListener()
@Override
public void onClick(View v)
);
【讨论】:
【参考方案3】:根据 Android API 文档:
ListFragment 有一个由单个列表视图组成的默认布局。 但是,如果您愿意,可以通过以下方式自定义片段布局 从 onCreateView(LayoutInflater, 视图组,捆绑包)。 为此,您的视图层次结构必须包含 id 为“@android:id/list”的 ListView 对象(或列表,如果它在 代码)
由于您没有发布片段的布局文件,我不确定这里出了什么问题。
以下代码是您使用 ListFragment 的默认列表视图时的样子。如果您使用 ListFragment,您应该利用可用的其他方法,例如 setListAdapter
和 onListItemClick
。您还可以在不使用 ListFragment(仅使用 Fragment)的情况下做同样的事情。
片段代码(修改了您的代码)
public class BasicFragment extends ListFragment
MyCustomAdapter adapter;
@Override
public void onCreate(Bundle si)
super.onCreate(si);
@Override
public void onActivityCreated(Bundle savedInstanceState)
super.onActivityCreated(savedInstanceState);
// not sure what you are doing here but data fetch should be asynchronous if it interacts with DB or makes network call
FetchedData DT = FetchedData.StaticDataTransfer();
RecepiesProperties[] AryObjaz = DT.getData();
getdata(AryObjaz);
adapter = new MyCustomAdapter(getActivity(), R.layout.listview_layout, Dataset);
setListAdapter(adapter);
@Override
public void onListItemClick(ListView l, View v, int position, long id)
Toast t = Toast.makeText(getActivity(), "Message",
Toast.LENGTH_SHORT);
t.show();
另外我修改了你的适配器代码来帮助回收视图,你当前的代码没有使用视图回收并且总是在膨胀视图。
适配器代码:
public class MyCustomAdapter extends ArrayAdapter<Recipes>
Context context;
int layoutResourceId;
Recipes data[] = null;
Typeface typeface;
public ImageLoader imageLoader;
private LayoutInflater inflater;
public MyCustomAdapter(Context context, int textViewResourceId, Recipes[] dataset)
super(context, textViewResourceId, dataset);
this.layoutResourceId = textViewResourceId;
this.context = context;
this.data = dataset;
imageLoader = new ImageLoader(context.getApplicationContext());
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@Override
public View getView(int position, View convertView, ViewGroup parent)
View row = convertView;
RecipesHolder holder = null;
//recycling views
if(null == row)
row = inflater.inflate(layoutResourceId, parent, false);
holder = new RecipesHolder();
holder.imgIcon = (ImageView) row.findViewById(R.id.imageView1);
holder.txtTitle = (TextView) row.findViewById(R.id.title);
holder.category = (TextView) row.findViewById(R.id.category);
holder.source = (TextView) row.findViewById(R.id.source);
holder.country = (TextView) row.findViewById(R.id.country);
holder.readytime = (TextView) row.findViewById(R.id.readytime);
holder.tips = (Button) row.findViewById(R.id.tips);
holder.fav = (Button) row.findViewById(R.id.fav);
row.setTag(holder);
else
holder = (RecipesHolder)row.getTag();
Recipes ap = data[position];
imageLoader.DisplayImage(ap.getIMAGENAME240(), holder.imgIcon);
holder.txtTitle.setText(ap.getNAME());
holder.category.setText(ap.getCATEGORY());
holder.source.setText(ap.getSOURCE());
holder.country.setText(ap.getCOUNTRY());
holder.readytime.setText(ap.getREADYTIME());
return row;
static class RecipesHolder
ImageView imgIcon;
TextView txtTitle;
TextView category;
TextView source;
TextView country;
TextView readytime;
Button tips;
Button fav;
【讨论】:
【参考方案4】:当您膨胀视图时,您的视图中似乎有 2 个按钮:
这个row.findViewById(R.id.tips);
还有这个row.findViewById(R.id.fav);
您应该删除这些按钮(如果您不想点击它们,请将它们替换为文本视图)
或者如果你想要这些按钮的点击,你可以为每个按钮使用 OnClickListeners,为整个视图使用另一个 OnClickListener。
示例
@Override
public View getView(int position, View convertView, ViewGroup parent)
View row = convertView;
//we only inflate if the row is null!!
if(row == null)
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
RecipesHolder holder = new RecipesHolder();
holder.imgIcon = (ImageView) row.findViewById(R.id.imageView1);
holder.txtTitle = (TextView) row.findViewById(R.id.title);
holder.category = (TextView) row.findViewById(R.id.category);
holder.source = (TextView) row.findViewById(R.id.source);
holder.country = (TextView) row.findViewById(R.id.country);
holder.readytime = (TextView) row.findViewById(R.id.readytime);
holder.tips = (Button) row.findViewById(R.id.tips);
holder.fav = (Button) row.findViewById(R.id.fav);
//we set the tag of the view to this holder so we can get it everytime
row.setTag(holder);
//change this to final so that you can use it inside your click listeners
final Recipes ap = data[position];
//here we get the holder of the view from its tag
RecipesHolder holder = (RecipesHolder) row.getTag();
//no changes to ur setup
imageLoader.DisplayImage(ap.getIMAGENAME240(), holder.imgIcon);
holder.txtTitle.setText(ap.getNAME());
holder.category.setText(ap.getCATEGORY());
holder.source.setText(ap.getSOURCE());
holder.country.setText(ap.getCOUNTRY());
holder.readytime.setText(ap.getREADYTIME());
//now the click listeners
//tips button
holder.tips.setOnClickListener(new OnClickListener()
public void onClick(View v)
//tips has been clicked
//do whatever you want with `ap`
);
//fav button
holder.fav.setOnClickListener(new OnClickListener()
public void onClick(View v)
//fav has been clicked
//do whatever you want with `ap`
);
//whole item click
row.setOnClickListener(new OnClickListener()
public void onClick(View v)
//the row has been clicked
//do whatever you want with `ap`
);
return row;
【讨论】:
@jeevamuthu 带有android:id="@+id/fav"
和android:id="@+id/tips"
的按钮在哪里
现在查看 listview_layout.xml。我也需要点击列表视图和列表视图行中的按钮
@jeevamuthu 我已经编辑了答案并修复了您的 getView
函数。 cmets 应该让您更好地了解 Holder,当然还有点击监听器
感谢响应我需要在单击该列表视图行时显示另一个片段。我能做些什么呢?
让我们continue this discussion in chat【参考方案5】:
将以下代码放入onViewCreated()
方法中:
@Override
public void onViewCreated(View view, Bundle savedInstanceState)
ListView list = (ListView) view.findViewById(android.R.id.list);
list.setOnItemClickListener(new OnItemClickListener()
public void onItemClick(AdapterView<?> parent, View view,
int position, long id)
Toast t = Toast.makeText(getActivity(), "Message",
Toast.LENGTH_SHORT);
t.show();
);
问题可能在于onViewCreate()中还没有构造视图,所以不建议在那里设置监听器。
【讨论】:
感谢您的回复。我已经实现了这个方法,但没有用。请提供任何样品。 吐司没有出现? yes.toast 没有出现。我已经将 CustomAdapter 用于列表视图。 向我们展示您的“MyCustomAdapter”类。 请参阅 MyCustomAdapter 类。【参考方案6】: lv.setOnItemClickListener(new OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id)
//your code
);
我认为这应该可行
【讨论】:
【参考方案7】:Adapter有方法areAllItemsEnabled(),可能有用。
公共抽象布尔 areAllItemsEnabled ()
指示是否启用此适配器中的所有项目。如果此方法返回的值随时间变化,不保证会生效。如果为 true,则表示所有项目都是可选择和可点击的(没有分隔符。)
【讨论】:
【参考方案8】:@Override
public void onListItemClick(ListView l, View v, int position, long id)
// TODO Auto-generated method stub
super.onListItemClick(l, v, position, id);
【讨论】:
【参考方案9】:只需将android:focusable="false" android:clickable="false"
放入布局中。对于所有文本视图、按钮等。
问题解决了。
【讨论】:
【参考方案10】:我遇到了类似的问题,我花了很长时间才弄清楚出了什么问题。 以前我的片段的 onListItemClick() 打开了新的活动,但是在返回片段后,onListItemClick() 监听器不再工作了。
@Override
public void onListItemClick(ListView l, View v, int position, long id)
super.onListItemClick(l, v, position, id);
// additional code (e.g. open new activity)
这个问题是通过在我的自定义 ArrayAdapter 中创建一个侦听器来解决的。我将此代码放在 getView() 中:
rowView.setOnClickListener(new View.OnClickListener()
final int p = position;
@Override
public void onClick(View v)
Log.d("FeedListAdapter", "onClick()");
openPost(p); // for example
);
我已经熬夜解决了这个问题(现在是早上 8 点),我想我应该将我的解决方案发布给处于类似位置的其他人 :)
【讨论】:
以上是关于Onclicklistener 在片段列表视图中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
onClickListener 在 Recycler Adapter 类中不起作用
Android onClickListener 在复合视图中不起作用