将 Button onClick 传递回主要活动的最佳方法?

发布于 2024-12-03 05:30:30 字数 1182 浏览 5 评论 0原文

我有一个超级 TestUI 应用程序。它有一个带有按钮的网格视图。

我希望按钮单击的内容传递回主活动,以便它可以更新其状态。

遗憾的是,这些按钮窃取了点击次数。所以典型的情况是:

        gridview.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
                Toast.makeText(TestUI.this, "" + position, Toast.LENGTH_SHORT).show();
            }
        });

没有被调用。

相反,在适配器定义中:

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

    Button gridItem;

    if (convertView == null) {  // if it's not recycled, initialize some attributes
        gridItem = new Button(mContext);
    } else {
        gridItem = (Button) convertView;
    }
    gridItem.setText("button " + String.valueOf(position));
    gridItem.setClickable(true);
    gridItem.setFocusable(false);
    gridItem.setOnClickListener(new MyOnClickListener(position, mContext));

    return gridItem;

它由实现 OnClickListener 接口的类 MyOnClickListener 支持。但是,如果我这样做,我仍然需要回调主活动,以某种方式它需要知道在控制程序状态时已完成某些操作。

那么通过单击按钮更新“根”类/活动状态的最佳方法是什么?

我知道这是一个基本的 OO 问题,但我主要用 ASM 和 C 编写,所以坦率地说我不知道​​。

I have a super TestUI application. It has a gridview with buttons in them.

I want word of the button click to be passed back to the main Activity, so that it can update its state.

Sadly the buttons steal the clicks. So the typical:

        gridview.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
                Toast.makeText(TestUI.this, "" + position, Toast.LENGTH_SHORT).show();
            }
        });

Does not get called.

Instead in the adapter definition:

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

    Button gridItem;

    if (convertView == null) {  // if it's not recycled, initialize some attributes
        gridItem = new Button(mContext);
    } else {
        gridItem = (Button) convertView;
    }
    gridItem.setText("button " + String.valueOf(position));
    gridItem.setClickable(true);
    gridItem.setFocusable(false);
    gridItem.setOnClickListener(new MyOnClickListener(position, mContext));

    return gridItem;

Which is backed with a class MyOnClickListener that implements the OnClickListener interface. However if I do it this way I still need a call back to the main activity, somehow it needs to know that something was done as it controls the program state.

So what is the best way to update the "root" class/activities' state from a button click?

I know this a basic OO question but I mostly write in ASM and C so I frankly just don't know.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

许一世地老天荒 2024-12-10 05:30:30

为什么需要2个onClickListeners。从 onItemClickListener 您必须到主要活动,您不能完成所有需要做的工作吗?适配器必须执行 MyOnClickListener 工作吗?

您可以从主活动中设置 gridItem.setOnClickListener。无需每次都创建新的 ListenerObject。

您只需要一个 xml 即可膨胀到包含 Button 的 getView

  <Button android:text="Handle me"
     android:id="@+id/btnHandleMe"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:onClick="buttonHandler"
     android:clickable="true">

并为您的活动创建此函数。

public void buttonHandler(View v) {
        // Do your stuff here that new MyOnClickListener(position, mContext) whould do.
    }

您可以通过向适配器添加标签来获取此按钮在列表/网格中填充的行/列的位置。

在 getView 中添加

 gridItem.setTag(position)

并从 buttonHandler 中检索它

if(v.getTag instance of Integer)
int position = (Integer)v.getTag();

所以现在您处理来自活动的所有点击,并且默认情况下会通知活动。

Why do you need to have 2 onClickListeners. From the onItemClickListener you have to the main activity can't you do all the work you need to do? Is a necessary for the adapter to do the MyOnClickListener work?

You can set the gridItem.setOnClickListener from the main activity. No need to create a new ListenerObject every time.

You just need a xml to inflate to getView containing a Button

  <Button android:text="Handle me"
     android:id="@+id/btnHandleMe"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:onClick="buttonHandler"
     android:clickable="true">

and create this function to your activity.

public void buttonHandler(View v) {
        // Do your stuff here that new MyOnClickListener(position, mContext) whould do.
    }

You can get the position of the row/column that this button is populated in the list/grid by adding a tag to the adapter.

In getView add

 gridItem.setTag(position)

and to retreive it from buttonHandler

if(v.getTag instance of Integer)
int position = (Integer)v.getTag();

So now you handle all clicks from the activity and by default the activity is notified.

轮廓§ 2024-12-10 05:30:30

正如您所说,您的 getView 方法位于适配器类内部。但是适配器会获取“上下文”的副本,您的 getView 方法可以访问该副本。上下文是所有活动和服务的超类。通过这个对象你可以完成Activity的许多基本操作。从你的例子中,我了解到你想敬酒。这可以使用来完成。

public View getView(int position, View convertView, ViewGroup parent) {
    //usual getView stuff goes first

    gridItem.setOnClickListener(new OnClickListener(){
        public onClick(View v){
            Toast.makeText(mContext, "" + position, Toast.LENGTH_SHORT).show();
        }
    }
}

简而言之,您的 MyOnClickListener 类需要使用 mContext 变量来与根活动交互。

编辑
我意识到我在上面的回答中犯了一个错误。我查看了 http://developer.android.com/resources 上的示例/tutorials/views/hello-gridview.html 并意识到您不限于使用 Context。你可以使用类似

public class MyActivity extends Activity {
    public int a = 0;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        GridView gridview = (GridView) findViewById(R.id.gridview);
        gridview.setAdapter(new ImageAdapter(this));
    }
}

public class ImageAdapter extends BaseAdapter {
    private MyActivity myAct;
    public ImageAdapter(MyActivity c) {
        myAct= c;
    }
    public View getView(int position, View convertView, ViewGroup parent) {
        //usual getView stuff goes first

        gridItem.setOnClickListener(new OnClickListener(){
            public onClick(View v){
                myAct.a = position;
            }
        }
    }
}

希望这就是你想做的事情。

As you said, your getView method is inside the adapter class. But the adapter gets a copy of the "context", which your getView method has access to. Context is a super-class of all Activities and Services. Through this object you can do many of the basic operations of an Activity. From your example, I understand that you would like to show a toast. This can be done using

public View getView(int position, View convertView, ViewGroup parent) {
    //usual getView stuff goes first

    gridItem.setOnClickListener(new OnClickListener(){
        public onClick(View v){
            Toast.makeText(mContext, "" + position, Toast.LENGTH_SHORT).show();
        }
    }
}

So in short, your MyOnClickListener class needs to used the mContext variable for interacting with the root activity.

Edit
I realized that I made a mistake in the above answer. I looked at the sample on http://developer.android.com/resources/tutorials/views/hello-gridview.html and realized that you aren't restricted to using Context. You could use something like

public class MyActivity extends Activity {
    public int a = 0;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        GridView gridview = (GridView) findViewById(R.id.gridview);
        gridview.setAdapter(new ImageAdapter(this));
    }
}

public class ImageAdapter extends BaseAdapter {
    private MyActivity myAct;
    public ImageAdapter(MyActivity c) {
        myAct= c;
    }
    public View getView(int position, View convertView, ViewGroup parent) {
        //usual getView stuff goes first

        gridItem.setOnClickListener(new OnClickListener(){
            public onClick(View v){
                myAct.a = position;
            }
        }
    }
}

Hopefully that is what you wanted to do.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文