如何在自定义适配器上实现 onClickListener?

Posted

技术标签:

【中文标题】如何在自定义适配器上实现 onClickListener?【英文标题】:How to implement onClickListener on a custom adapter? 【发布时间】:2015-10-24 15:10:35 【问题描述】:

我正在学习制作一个简单的时间表管理应用程序。 我有一个显示的课程列表。列表中的每个项目都是一个文本视图 + 一个删除按钮。我的列表项中的 onClick 侦听器未按预期工作。当我单击删除按钮时,它工作正常。但是,当用户单击列表项的文本视图时,我想打开一些其他活动。

代码:

ShowAll.java(我在其中显示类列表的主要活动)

package com.example.android.mytimetable;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

import java.util.ArrayList;


public class ShowAll extends ActionBarActivity 
    private ArrayAdapter<String> adapter ;
    ArrayList <ClassDetail> classesDetail ;
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_show_all);
        this.bindAdapter();

        ListView listView = (ListView) this.findViewById(R.id.class_list);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() 
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) 
                Log.v("Item", "clicked");
                Intent intent = new Intent(view.getContext(), ShowAllClicked.class);
                ClassDetail classDetail = classesDetail.get(i);
                Bundle bundle = new Bundle();
                bundle.putString("CLASS_NAME", classDetail.class_name);
                bundle.putString("BUILDING", classDetail.building);
                bundle.putString("MONDAY_START", classDetail.monday_start);
                bundle.putString("MONDAY_END", classDetail.monday_end);
                bundle.putString("TUESDAY_START", classDetail.tuesday_start);
                bundle.putString("TUESDAY_END", classDetail.tuesday_end);
                bundle.putString("WEDNESDAY_START", classDetail.wednesday_start);
                bundle.putString("WEDNESDAY_END", classDetail.wednesday_end);
                bundle.putString("THURSDAY_START", classDetail.thursday_start);
                bundle.putString("THURSDAY_END", classDetail.thursday_end);
                bundle.putString("FRIDAY_START", classDetail.friday_start);
                bundle.putString("FRIDAY_END", classDetail.friday_end);
                intent.putExtras(bundle);
                startActivity(intent);
            
        );
    

    void bindAdapter() 
        DBHelper db = new DBHelper(this);
        classesDetail = db.getClassesDetail();
        ArrayList <String> classes = new ArrayList<>();
        for(int i = 0 ; i < classesDetail.size() ; i++) 
            Log.v("Adding ", classesDetail.get(i).class_name);
            classes.add(classesDetail.get(i).class_name);
        
        if(classes.size() == 0)
            ((TextView) this.findViewById(R.id.holiday)).setText(getString(R.string.noClass));
        CustomArrayAdapter customArrayAdapter = new CustomArrayAdapter(classes, this);
        ((ListView) this.findViewById(R.id.class_list)).setAdapter(customArrayAdapter);
    

    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_show_all, menu);
        return true;
    

    @Override
    public boolean onOptionsItemSelected(MenuItem item) 
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.

        return super.onOptionsItemSelected(item);
    

activity_show_all.xml(ShowAll.java的xml布局)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_
    android:layout_ android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="com.example.android.mytimetable.ShowAll"
    android:orientation="vertical">

    <ListView
        android:layout_
        android:layout_
        android:id="@+id/class_list"/>

    <TextView
        android:layout_
        android:layout_
        android:id="@+id/holiday"/>

</LinearLayout>

CustomArrayAdapter.java(自定义数组适配器文件)

package com.example.android.mytimetable;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListAdapter;
import android.widget.TextView;

import java.util.ArrayList;

/**
 * Created by Aman Goel on 02-08-2015.
 */
public class CustomArrayAdapter extends BaseAdapter implements ListAdapter 
    private ArrayList <String> list = new ArrayList<String>();
    private Context context;

    public CustomArrayAdapter(ArrayList <String> list, Context context) 
        this.list = list;
        this.context = context;
    

    @Override
    public int getCount() 
        return list.size();
    

    @Override
    public Object getItem(int pos) 
        return list.get(pos);
    

    @Override
    public long getItemId(int pos) 
        return 0;
    

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) 
        View view = convertView;
        if(view == null) 
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.list_item, null);
        

        ((TextView) view.findViewById(R.id.list_item)).setText(list.get(position));

        Button deleteBtn = (Button) view.findViewById(R.id.delete);

        deleteBtn.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                DBHelper db = new DBHelper(context);
                db.deleteClass(list.get(position));
                list.remove(position);
                notifyDataSetChanged();
            
        );
        return view;
    

list_item.xml(每个列表视图的布局)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:orientation="horizontal">

    <TextView
        android:layout_
        android:layout_
        android:minHeight="?android:attr/listPreferredItemHeight"
        android:gravity="center_vertical"
        android:id="@+id/list_item"
        android:focusableInTouchMode="false"
        android:clickable="false"
        android:focusable="false"/>

    <Button
        android:layout_
        android:layout_
        android:text="@string/delete"
        android:id="@+id/delete"/>

</LinearLayout>

我试图从这里寻求帮助:Set onClickListener into custom adapter 和这里:Where should I place the onClickListener on a Custom ListView?

但是,我仍然无法使适配器工作。任何帮助将不胜感激

【问题讨论】:

单击列表项时会发生什么?单击项目时按钮是否获得焦点?? 在文档 (developer.android.com/reference/android/widget/…) 中,他们说 view 参数是被点击的 AdapterView 中的视图。也许您可以检查视图类型。如果是 TextView,您可以打开活动。 @Raghunandan,当我点击它时没有任何反应 @AmanGoel 没有关注焦点??你在 logcat 中没有看到Log.v("Item", "clicked"); 【参考方案1】:

设置自定义适配器getview函数

TextView lst_tv=(TextView)view.findViewById(R.id.list_item);
lst_tv.setOnClickListener(new OnClickListener() 

    @Override
    public void onClick(View v) 
        // TODO Auto-generated method stub

    
);

【讨论】:

【参考方案2】:

customArrayAdapter.setOnItemClickListener(...)

【讨论】:

以上是关于如何在自定义适配器上实现 onClickListener?的主要内容,如果未能解决你的问题,请参考以下文章

如何在自定义 WP_Query Ajax 上实现分页

onItemClickListener 在自定义 ListView 的其他行上实现

jQuery 在自定义插件上实现销毁方法

在自定义视图/uiview 子类上实现 iphone 的复制/粘贴控件

在自定义适配器上使用.getFilter()时出现问题(未正确过滤)(Android)

如何使用空侦听器在kotlin中的适配器上实现点击侦听器?