当前位置: 首页 > 面试题库 >

ListView行按钮:如何创建将View.OnClickListener连接到ListView每行按钮的自定义适配器?

赵修诚
2023-03-14
问题内容

我希望ListView包含按钮,但是设置按钮的xml属性onClick =“ myFunction”,然后在活动中放置公共void
myFunction(android.view.View
view)方法会导致NoSuchMethodException(堆栈跟踪为null)就像onclick侦听器在那里一样被抛出,它不会触发myFunction(…)并导致活动关闭。

如何创建将View.OnClickListener连接到ListView每行上的按钮的自定义适配器?

我的ListView如下创建…

[activity.java内容..]

public void myFunction(android.view.View view)
{
    //Do stuff
}

[activity.xml内容..]

<LinearLayout xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".FrmCustomerDetails" >
    <ListView android:id="@+id/LstCustomerDetailsList" android:layout_width="fill_parent" android:layout_height="0dip" android:layout_weight="1" android:clickable="true" android:clipChildren="true" android:divider="@null" android:dividerHeight="0dp" android:fastScrollEnabled="true" android:footerDividersEnabled="false" android:headerDividersEnabled="false" android:requiresFadingEdge="vertical" android:smoothScrollbar="true" />
</LinearLayout>

[activity_row_item.xml内容..]

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/Llt" android:layout_width="match_parent" android:layout_height="match_parent" >
    <Button android:id="@+id/Btn" android:text="Click me" android:onClick="myFunction" />
</LinearLayout>

问题答案:

这是创建自定义适配器的方法,该方法通过每行一个按钮将View.OnClickListener连接到ListView。

1.为典型的行创建布局

在这种情况下,该行由三个视图组件组成:

  • 名称(EditText)
  • 值(EditText:inputType =“ numberDecimal”)
  • 删除(按钮)

Xml

pay_list_item.xml的布局如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <EditText
        android:id="@+id/pay_name"
        android:layout_width="0dp"
        android:layout_height="fill_parent"
        android:layout_weight="2"
        android:hint="Name" />

    <EditText
        android:id="@+id/pay_value"
        android:layout_width="0dp"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:inputType="numberDecimal"
        android:text="0.0" />

    <Button
        android:id="@+id/pay_removePay"
        android:layout_width="100dp"
        android:layout_height="fill_parent"
        android:text="Remove Pay"
        android:onClick="removePayOnClickHandler" />

</LinearLayout>

注意:该按钮在xml布局文件中定义了onClick处理程序,因为我们希望将其操作引用到特定的列表项。

这样做意味着处理程序将在“活动”文件中实现,并且每个按钮都将知道它属于哪个列表项。

2.创建列表项适配器

这是Java类,它是pay_list_item.xml的控制器。

它保留其所有视图的引用,还将这些引用放入标记中,从而扩展了ArrayAdapter接口。

适配器:

public class PayListAdapter extends ArrayAdapter<Payment> {

    private List<Payment> items;
    private int layoutResourceId;
    private Context context;

    public PayListAdapter(Context context, int layoutResourceId, List<Payment> items) {
        super(context, layoutResourceId, items);
        this.layoutResourceId = layoutResourceId;
        this.context = context;
        this.items = items;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;
        PaymentHolder holder = null;

        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        row = inflater.inflate(layoutResourceId, parent, false);

        holder = new PaymentHolder();
        holder.Payment = items.get(position);
        holder.removePaymentButton = (ImageButton)row.findViewById(R.id.pay_removePay);
        holder.removePaymentButton.setTag(holder.Payment);

        holder.name = (TextView)row.findViewById(R.id.pay_name);
        holder.value = (TextView)row.findViewById(R.id.pay_value);

        row.setTag(holder);

        setupItem(holder);
        return row;
    }

    private void setupItem(PaymentHolder holder) {
        holder.name.setText(holder.Payment.getName());
        holder.value.setText(String.valueOf(holder.Payment.getValue()));
    }

    public static class PaymentHolder {
        Payment Payment;
        TextView name;
        TextView value;
        ImageButton removePaymentButton;
    }
}

在这里,我们列出了付款类别的项目。

这里有三个最重要的元素:

  • PayListAdapter构造函数:设置一些私有字段并调用超类构造函数。它还获取付款清单对象。它的实施是强制性的。
  • PaymentHolder:静态类,其中包含对我必须在此列表项中设置的所有视图的引用。我还将保留引用该特定项目的Payment对象在列表中。我将其设置为ImageButton的标记,这将帮助我在列表中找到该用户想要删除的“付款”项
  • 重写getView方法:由超类调用。其目标是返回单个列表行。我们创建其字段并设置其值,并将其存储在静态持有人中。然后将持有人放入行的tag元素中。请注意,存在性能问题,因为每次显示该行时都会重新创建该行。我曾经在isCreated等持有人中添加一些标志,并在创建行后将其设置为true。那么您可以添加if语句并读取标签的持有人,而不是从头开始创建它。

Payment.java到目前为止非常简单,看起来有点像BasicNameValuePair:

public class Payment implements Serializable {
    private String name = "";
    private double value = 0;

    public Payment(String name, double value) {
        this.setName(name);
        this.setValue(value);
    }
...
}

每个未显示的专用字段都有其他获取和设置。

3.将ListView添加到活动布局xml文件中

以最简单的形式,将这个视图添加到活动布局就足够了:

<ListView 
    android:id="@+id/EnterPays_PaysList"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">
</ListView>

4.在活动Java代码中将适配器设置为此列表视图

为了在ListView中显示项目,您需要设置其适配器并将其映射到其他一些Payment对象的ArrayList(因为我在这里扩展了Array适配器)。这是负责将适配器绑定到editPersonData.getPayments()ArrayList的代码:

PayListAdapter adapter = new PayListAdapter(AddNewPerson.this, R.layout.pay_list_item, editPersonData.getPayments());
ListView PaysListView = (ListView)findViewById(R.id.EnterPays_PaysList);
PaysListView.setAdapter(adapter);

5.向ListView(及其适配器)添加/删除项目

适配器的处理方式与其他ArrayList一样,因此向其添加新元素非常简单:

Payment testPayment = new Payment("Test", 13);
adapter.add(testPayment);
adapter.remove(testPayment);

6.处理“删除付款”按钮单击事件

在显示ListView的活动代码中,添加将处理remove按钮click动作的公共方法。方法名称必须与pay_list_item.xml中的名称完全相同:

android:onClick="removePayOnClickHandler"
The method body is as follows:

public void removePayOnClickHandler(View v) {
    Payment itemToRemove = (Payment)v.getTag();
    adapter.remove(itemToRemove);
}

付款对象存储在ImageButton的Tag元素中。现在就足以从Tag中读取它,并将其从适配器中删除。

7.合并删除确认对话框窗口

可能您还需要通过在确认对话框中询问其他问题来确保用户有意按下了删除按钮。

对话

a)创建对话框的ID常量

这只是对话框的ID。在当前活动处理的任何其他对话框窗口中,它应该是唯一的。我这样设置:

protected static final int DIALOG_REMOVE_CALC = 1;
protected static final int DIALOG_REMOVE_PERSON = 2;

b)构建对话框

我使用此方法来构建对话框窗口:

private Dialog createDialogRemoveConfirm(final int dialogRemove) {
    return new AlertDialog.Builder(getApplicationContext())
    .setIcon(R.drawable.trashbin_icon)
    .setTitle(R.string.calculation_dialog_remove_text)
    .setPositiveButton(R.string.calculation_dialog_button_ok, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            handleRemoveConfirm(dialogRemove);
        }
    })
    .setNegativeButton(R.string.calculation_dialog_button_cancel, null)
    .create();
}

这里使用AlertDialog构建器模式。我不处理NegativeButton单击动作-
默认情况下,该对话框只是隐藏的。如果单击对话框的确认按钮,则会调用我的handleRemoveConfirm回调,并根据对话框的ID执行操作:

protected void handleRemoveConfirm(int dialogType) {
    if(dialogType == DIALOG_REMOVE_PERSON){
        calc.removePerson();
    }else if(dialogType == DIALOG_REMOVE_CALC){
        removeCalc();
    }
}

c)显示对话框

单击删除按钮后显示对话框。showDialog(int)是Android的Activity的方法:

OnClickListener removeCalcButtonClickListener = new OnClickListener() {
    public void onClick(View v) {
        showDialog(DIALOG_REMOVE_CALC);
    }
};

showDialog(int)方法调用onCreateDialog(也在Activity类中定义)。覆盖它,并告诉您的应用程序如果请求showDialog时该怎么做:

@Override
protected Dialog onCreateDialog(int id) {
    switch (id) {
    case DIALOG_REMOVE_CALC:
        return createDialogRemoveConfirm(DIALOG_REMOVE_CALC);
    case DIALOG_REMOVE_PERSON:
        return createDialogRemoveConfirm(DIALOG_REMOVE_PERSON);
    }
}


 类似资料:
  • 如何在JavaFX中创建每行都有删除按钮和删除按钮操作?

  • 我尝试按照幻灯片youtube 6部分教程创建一个带有自定义行的列表视图。在他的教程中,他使用了1个图像和2个文本视图,我需要3个图像和3个文本视图,当我运行应用程序时,它在尝试加载列表视图时崩溃。 -------------家庭单行.xml----------------------- - Homelistview.xml - Homeactivitylistview.java 04-22 15

  • 我有一个包含我的数据的listView,但我需要能够按下向上滚动的按钮(如果listView可以向上滚动)和向下滚动的按钮(如果listView可以向下滚动),而不是使用滚动条滚动 listView可以转到的最大Y位置 listView滚动到的当前Y位置 使用这些值,我可以编写其余的代码。

  • 在我的活动中,我有一个listview和一个按钮。每一个都有各自的目的。 我的listview显示另一个活动中的项目详细信息。 问题是如何在相同的活动中为按钮实现onClickListener?

  • 我正在开发一个android应用程序,其中我制作了一个ListView。我必须为ListView中的每一行添加两个按钮。这两个按钮分别是“添加”和“删除”。当用户选择其中一个按钮时,应采取一些措施。我该怎么做?

  • 如何处理ListView中的每个按钮单击?活动课 如何管理ListView中每个项目的按钮单击?我尝试了许多方法…如何解决此问题?请任何人帮帮我...