ListView中的CardViews:卡点击不执行点击侦听器

时间:2018-09-25 13:01:32

标签: android listview android-cardview

我正在实现CardViews的ListView。 但是,当我单击时,我可以看到被单击的卡,但不执行侦听器。 所有卡均已正确渲染并单击,但未执行侦听器功能。

Activity.java

final List<String> deviceStringList = new ArrayList<String>();
        deviceStringList.add("Device 1");
        deviceStringList.add("Device 2");
        deviceStringList.add("Device 3");
        deviceStringList.add("Device 4");

        String[] deviceStringArray = deviceStringList.toArray(new String[deviceStringList.size()]);
        DevicesListViewAdapter cardListAdapter = new DevicesListViewAdapter(this, deviceStringArray);
        ListView deviceCardsListView = (ListView) findViewById(R.id.deviceCardsListView);
        deviceCardsListView.setAdapter(cardListAdapter);

        final List<String> finalDeviceList = deviceStringList;
        deviceCardsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                Toast toast = Toast.makeText(getApplicationContext(), finalDeviceList.get(position), Toast.LENGTH_LONG);
                toast.show();
            }
        });

ListViewAdapter.java

public class DevicesListViewAdapter extends ArrayAdapter<String>
{
    private final Activity context;
    private final String[] deviceName;

    public DevicesListViewAdapter(@NonNull Activity context, String[] deviceName) {
        super(context, R.layout.device_card_layout, deviceName);

        this.context = context;
        this.deviceName = deviceName;
    }

    public View getView(int position, View view, ViewGroup parent) {
        LayoutInflater inflater = context.getLayoutInflater();
        View cardView = inflater.inflate(R.layout.device_card_layout, null, true);

        Button cardBtn = (Button) cardView.findViewById(R.id.cardButton);
        cardBtn.setText(deviceName[position]);

        return cardView;
    }
}

CardView布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    android:orientation="vertical"
    android:paddingBottom="@dimen/cardview_default_elevation"
    android:paddingLeft="@dimen/cardview_default_elevation"
    android:paddingRight="@dimen/cardview_default_elevation"
    android:paddingTop="@dimen/cardview_default_elevation"
    android:clickable="true"
    android:focusable="true"
    android:foreground="?android:selectableItemBackground">

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="300dp"
    card_view:cardCornerRadius="6dp"
    android:layout_margin="10dp"
    android:clickable="true"
    android:focusable="true"
    android:foreground="?android:selectableItemBackground">

    <android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="5dp">

        <Button
            android:id="@+id/cardButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginBottom="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:background="@drawable/add_device_btn"
            android:text=""
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </android.support.constraint.ConstraintLayout>


</android.support.v7.widget.CardView>
</LinearLayout>

我在做什么错? 谢谢。

4 个答案:

答案 0 :(得分:1)

解决方案:

删除此:

deviceCardsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

           Toast toast = Toast.makeText(getApplicationContext(), finalDeviceList.get(position), Toast.LENGTH_LONG);
            toast.show();
        }
});

并这样写:

cardBtn.setOnClickListener(...) {
    onClick() {

         Toast toast = Toast.makeText(getApplicationContext(), "" + position, Toast.LENGTH_LONG);
        toast.show();

    }
}

在适配器内部,如下所示:

public View getView(int position, View view, ViewGroup parent) {
    LayoutInflater inflater = context.getLayoutInflater();
    View cardView = inflater.inflate(R.layout.device_card_layout, null, true);

    Button cardBtn = (Button) cardView.findViewById(R.id.cardButton);
    cardBtn.setText(deviceName[position]);

    .......(Write Here)

    return cardView;
}

希望有帮助。谢谢。

答案 1 :(得分:1)

请尝试将on click侦听器提供给主LinearLayout或CardView,而不是提供onItemClickListener。 OnItemClick不适用于可聚焦或具有可单击项的列表视图。因此,为列表中的项目定义点击侦听器应该可以解决问题。

供参考

  LinearLayout mainView = (LinearLayout) findViewById(R.id.id_of_LL);
                    mainView.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            Toast toast = Toast.makeText(getApplicationContext(), "" + position, Toast.LENGTH_LONG);
                            toast.show();

                        }
                    });

答案 2 :(得分:1)

您是否尝试过为适配器中的每个视图注册onClick侦听器,然后通过接口与父活动进行通信?例如,在您的适配器类中创建一个接口

public interface CardListener {
    void onSelected();
}

在适配器中,定义一个私有变量,以存储要通过setter方法传递的接口实现的引用。像这样:

private CardListener listener;

在适配器中定义设置器

public void setListener(CardListener listener) { this.listener = listener; }

然后在将数据绑定到getView方法中时,请执行以下操作

cardBtn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
       if(listener != null) { listener.onSelected(); }
    }
});

最后,您可以在活动中像这样设置回调定义

adapter.setListener(new CardListener() {
    @Override
    public void onSelected() { // Do something here };
});

这将允许您定义许多自定义单击操作,以防您需要对卡片视图中不同视图上的单个单击操作进行某些操作。它还允许您来回传递任何适配器数据,并允许您以更分隔的方式将适配器逻辑与活动逻辑分开。希望这会有所帮助。

有关更多信息,请查看以下有用的资源:https://guides.codepath.com/android/Using-an-ArrayAdapter-with-ListView#attaching-event-handlers-within-adapter

答案 3 :(得分:0)

android:clickable =“ true”更改为android:clickable =“ false”

如果您使用listview.setonclick,则cardview clickable必须为false