Android - 带有自定义 BaseAdapter 的 Gridview,创建 onclicklistener

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20052631/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 02:13:56  来源:igfitidea点击:

Android - Gridview with Custom BaseAdapter, create onclicklistener

androidgridviewonclicklistenerbaseadapter

提问by Christos Baziotis

I have created a gridview which displays the letters of the alphabet. I populate the gridview with a string array using a custom BaseAdapter.

我创建了一个 gridview 来显示字母表中的字母。我使用自定义 BaseAdapter 用字符串数组填充 gridview。

What i want to do is to be able to get the value (letter) of the clicked cell. In order to verify that it works, i have created a TextView and i want when the user clicks on an item (cell) to set the text of the TextView with the value of the selected cell

我想要做的是能够获得点击单元格的值(字母)。为了验证它是否有效,我创建了一个 TextView,我希望当用户单击一个项目(单元格)时,将 TextView 的文本设置为所选单元格的值

enter image description here

在此处输入图片说明

I have made an attempt which doesn't work. Here is my code:

我做了一个没有用的尝试。这是我的代码:

activity_main.xml

活动_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    tools:ignore="MergeRootFrame" >

    <GridView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/myGridView"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:numColumns="7" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Large Text"
        android:id="@+id/feedback"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true" />
</RelativeLayout>

cell.xml

单元格.xml

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

    <Button
        android:id="@+id/grid_item"
        android:layout_gravity="center"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="05"
        android:textSize="20sp"
        android:enabled="true"
        android:clickable="true">
    </Button>

</LinearLayout>

MainActivity

主要活动

public class MainActivity extends Activity {

    private TextView text;
    private GridView gridView;
    private final String[] items = new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
            "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        text = (TextView) findViewById(R.id.feedback);

        gridView = (GridView) this.findViewById(R.id.myGridView);
        CustomGridAdapter gridAdapter = new CustomGridAdapter(MainActivity.this, items);
        gridView.setAdapter(gridAdapter);
        gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                text.setText((String) (gridView.getItemAtPosition(position)));
                Log.i("ITEM_CLICKED", "" + (String) (gridView.getItemAtPosition(position)));
            }
        });

    }
}

CustomGridAdapter

自定义网格适配器

public class CustomGridAdapter extends BaseAdapter {

    private Context context;
    private String[] items;
    LayoutInflater inflater;

    public CustomGridAdapter(Context context, String[] items) {
        this.context = context;
        this.items = items;
        inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    public View getView(int position, View convertView, ViewGroup parent) {

        if (convertView == null) {
            convertView = inflater.inflate(R.layout.cell, null);
        }
        Button button = (Button) convertView.findViewById(R.id.grid_item);
        button.setText(items[position]);

        return convertView;
    }

    @Override
    public int getCount() {
        return items.length;
    }

    @Override
    public Object getItem(int position) {
        return items[position];
    }

    @Override
    public long getItemId(int position) {
        return position;
    }
}

What am i doing wrong?

我究竟做错了什么?

Edit: It seems that the gridView.setOnItemClickListener(...); is not called/executed. I have changed it to this in order to check it and i see nothing in the logcat.

编辑:似乎 gridView.setOnItemClickListener(...); 不被调用/执行。我已将其更改为此以进行检查,但我在 logcat 中看不到任何内容。

gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Log.i("ON_ITEM_CLICK_LISTENER", "item clicked");
            }
        });

采纳答案by gunar

The problem in your case is that the button is consuming the click and it doesn't get to GridView. I see two options:

您的情况的问题是该按钮正在消耗点击并且它没有到达 GridView。我看到两个选项:

  1. The easy one: in cell.xmlhave these properties for your Button: android:clickable="false"and android:focusable="false"
  2. A grosso-modo: send the Activity as parameter to adapter and expose a public method from MainActivity. If you think of re-using the adapter, then send an abstract type of activity or an interface.
  1. 最简单的一个:cell.xml为您的Button:android:clickable="false"android:focusable="false"
  2. 大体模式:将 Activity 作为参数发送到适配器并从MainActivity. 如果您考虑重用适配器,则发送抽象类型的活动或接口。

Something as:

东西如:

public class MainActivity extends Activity {
    private TextView text;
    private GridView gridView;
    private final String[] items = new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
            "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        text = (TextView) findViewById(R.id.feedback);

        gridView = (GridView) this.findViewById(R.id.myGridView);
        CustomGridAdapter gridAdapter = new CustomGridAdapter(MainActivity.this, items);
        gridView.setAdapter(gridAdapter);

    }

    public void itemClicked(int position) {
        text.setText(items[position]);
    }
}

and in your adapter:

并在您的适配器中:

public class CustomGridAdapter extends BaseAdapter {

    private MainActivity context;
    private String[] items;
    LayoutInflater inflater;

    public CustomGridAdapter(MainActivity context, String[] items) {
        this.context = context;
        this.items = items;
        inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    public View getView(final int position, View convertView, ViewGroup parent) {

        if (convertView == null) {
            convertView = inflater.inflate(R.layout.cell, null);
        }
        Button button = (Button) convertView.findViewById(R.id.grid_item);
        button.setText(items[position]);
        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                context.itemClicked(position);
            }
        });

        return convertView;
    }

    @Override
    public int getCount() {
        return items.length;
    }

    @Override
    public Object getItem(int position) {
        return items[position];
    }

    @Override
    public long getItemId(int position) {
        return position;
    }
}

回答by saiful103a

Actually for gridview setOnItemClickListener you are not doing anything wrong. It's the cell view that is creating the problem. Try changing cell-view button to a textview, it should work. Right now when you tap on an item in a gridview the item is not actually clicked because your cell-view button has it's own implementation of OnClickListener, and that is why setOnItemClickListener is not getting called.

实际上对于 gridview setOnItemClickListener 你没有做错任何事。造成问题的是单元格视图。尝试将单元格视图按钮更改为文本视图,它应该可以工作。现在,当您点击 gridview 中的某个项目时,该项目实际上并未被单击,因为您的单元格视图按钮有自己的 OnClickListener 实现,这就是 setOnItemClickListener 没有被调用的原因。

回答by azerto00

You can use the setTag() adnd getTag() which allow you to put/get any type of object. So in the future, you will be able to pass anything (if you make the appropriate cast after)

您可以使用 setTag() 和 getTag() 来放置/获取任何类型的对象。所以在未来,你将能够传递任何东西(如果你在之后进行了适当的转换)

public View getView(int position, View convertView, ViewGroup parent) {

    if (convertView == null) {
        convertView = inflater.inflate(R.layout.cell, null);
    }

    Button button = (Button) convertView.findViewById(R.id.grid_item);
    button.setText(items[position]);
    convertView.setTag(items[position]); 
    return convertView;
}

AND

gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            String str = (String) view.getTag();
            text.setText(str);
            Log.i("ITEM_CLICKED", "" + (String) (gridView.getItemAtPosition(position)));
        }
    });