安卓按钮无法点击

3
我正在创建一个应用程序,它在顶部使用类似于片段的工具栏,上面有几个按钮。这些按钮是以编程方式添加的。
问题在于当我启动应用程序时,工具栏和按钮出现了,但是按钮无法被点击。当鼠标悬停在按钮上(我使用模拟器),或者点击按钮时,它们不会改变,也不会通知我的OnClickListener。然而,在下面的片段中的按钮和其他组件可以正常工作。

工具栏的代码:

public class ToolbarFragment extends Fragment implements 
View.OnClickListener{

public static final String LOG_KEY = "SM_TOOLBAR";

public static final String TO_ADD_FEED_KEY = "TO_ADD_FEED_KEY";
public static final String TO_ADD_PROFILE_KEY = "TO_ADD_PROFILE_KEY";
public static final String TO_ADD_FRIENDS_KEY = "TO_ADD_FRIENDS_KEY";

private Button feed;
private Button profile;
private Button friends;
private Button logout;

public ToolbarFragment() {
    // Required empty public constructor
}

private Button addButton(int stringID, LinearLayout linearLayout) {
    Button button = new Button(getContext());
    button.setText(stringID);
    button.setOnClickListener(this);
    linearLayout.addView(button);
    return button;
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    LinearLayout linearLayout = (LinearLayout)inflater.inflate(R.layout.fragment_toolbar, container, false);


    Bundle arguments = getArguments();
    if (arguments.getBoolean(TO_ADD_FEED_KEY)) {
        Log.i(LOG_KEY, "Created feed key");
        feed = addButton(R.string.feed, linearLayout);
    }
    if (arguments.getBoolean(TO_ADD_PROFILE_KEY)) {
        Log.i(LOG_KEY, "Created profile Key");
        profile = addButton(R.string.profile, linearLayout);
    }
    if (arguments.getBoolean(TO_ADD_FRIENDS_KEY)) {
        Log.i(LOG_KEY, "Created friends key");
        friends = addButton(R.string.friends, linearLayout);
    }
    logout = addButton(R.string.logout, linearLayout);

    return linearLayout;
}

@Override
public void onClick(View view) {
    Log.i(LOG_KEY, "A button was clicked.");
    if (getActivity() instanceof IToolbarCallback) {
        IToolbarCallback itc = (IToolbarCallback) getActivity();
        if (view.equals(feed)) {
            itc.feed();
        }
        if (view.equals(profile)) {
            itc.profile();
        }
        if (view.equals(friends)) {
            itc.friends();
        }
        if (view.equals(logout)) {
            itc.logout();
        }
    }
}

除了回调接口之外,没有其他相关的代码。

public interface IToolbarCallback {

void feed();

void profile();

void logout();

void friends();

这只是用于让宿主活动了解被单击的内容。最后,XML:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="project3.csc214.project23.Fragments.Toolbar.ToolbarFragment"
android:orientation="horizontal">

我使用一个构建器来创建碎片,以下是代码:

我使用一个构建器来创建碎片,以下是代码:

public class ToolbarBuilder {

private boolean addFeed;
private boolean addProfile;
private boolean addFriends;

private FragmentManager fragmentManager;
private int addToID;

public ToolbarBuilder(FragmentManager fragmentManager, int addToID) {
    this.fragmentManager = fragmentManager;
    this.addToID = addToID;
    addFeed = false;
    addProfile = false;
    addFriends = false;
}

public ToolbarBuilder addFeed() {
    addFeed = true;
    return this;
}

public ToolbarBuilder addProfile() {
    addProfile = true;
    return this;
}

public ToolbarBuilder addFriends() {
    addFriends = true;
    return this;
}

public void build() {
    Bundle bundle = new Bundle();
    bundle.putBoolean(ToolbarFragment.TO_ADD_FEED_KEY, addFeed);
    bundle.putBoolean(ToolbarFragment.TO_ADD_FRIENDS_KEY, addFriends);
    bundle.putBoolean(ToolbarFragment.TO_ADD_PROFILE_KEY, addProfile);
    ToolbarFragment toolbarFragment = new ToolbarFragment();
    toolbarFragment.setArguments(bundle);
    fragmentManager.beginTransaction().add(addToID, toolbarFragment).commit();
}

仅作澄清,据我所知,按钮没有接收到任何输入。它们不只是无法调用onClick,而是完全没有反应。就我所知,onClick已经正确设置,但这些按钮在某种基本层面上出现了故障。

情节变得复杂了。在其他活动中使用完全相同的设置似乎可以正常工作……据我所知,没有任何更改。

无论如何,我决定为这个活动硬编码,以便我可以继续开发应用程序的其他部分。感谢大家考虑这个问题。如果我弄清楚了发生了什么,我会再次发布帖子。


尝试将点击监听器添加到onViewCreated方法中,而不是onCreateView方法中。如果这样做不起作用,您能否提供有关片段实现方式的一些上下文信息。 - zgc7009
我不相信问题出在OnClick上(我已经尝试过了,没有帮助)。我认为是我创建按钮的方式有问题。 - Mystik
你尝试过将它添加到onViewCreated而不是onCreateView中吗?我曾经看到过这个过程对视图实例化产生有趣的影响。 - zgc7009
是的,还是没有效果。 - Mystik
3个回答

3
不要比较视图是否相等,而是比较它们的ID。这里是示例代码:

@Override
public void onClick(View view) {
    Log.i(LOG_KEY, "A button was clicked.");
    if (getActivity() instanceof IToolbarCallback) {
        IToolbarCallback itc = (IToolbarCallback) getActivity();
        if (view.equals(feed)) {
            itc.feed();
        }
        if (view.equals(profile)) {
            itc.profile();
        }
        if (view.equals(friends)) {
            itc.friends();
        }
        if (view.equals(logout)) {
            itc.logout();
        }
    }
}

需要做的是:

@Override
public void onClick(View view) {
    Log.i(LOG_KEY, "A button was clicked.");
    if (getActivity() instanceof IToolbarCallback) {
        IToolbarCallback itc = (IToolbarCallback) getActivity();
        if (view.getId() == feed.getId()) {
            itc.feed();
        }
        if (view.getId() == profile.getId()) {
            itc.profile();
        }
        if (view.getId() == friends.getId()) {
            itc.friends();
        }
        if (view.getId() == logout.getId()) {
            itc.logout();
        }
    }
}

此外,由于您正在自己创建视图,因此您还需要为它们分配ID。如果您的API级别是17+,则可以在视图上直接调用generateViewId(),Android将为您创建唯一的ID。请按以下方式操作:
private Button addButton(int stringID, LinearLayout linearLayout) {
    Button button = new Button(getContext());
    button.setText(stringID);
    button.setOnClickListener(this);
    linearLayout.addView(button);
    button.generateViewId();
    return button;
}

编辑: 你的代码看起来没问题,除了我上面指出的那个。我建议你尝试在 addButton 方法之外设置监听器:

private Button addButton(int stringID, LinearLayout linearLayout) {
    Button button = new Button(getContext());
    button.setText(stringID);
    linearLayout.addView(button);
    button.generateViewId();
    return button;
}


if (arguments.getBoolean(TO_ADD_FEED_KEY)) {
        Log.i(LOG_KEY, "Created feed key");
        feed = addButton(R.string.feed, linearLayout);
        feed.setOnClickListener(this);
    }
    if (arguments.getBoolean(TO_ADD_PROFILE_KEY)) {
        Log.i(LOG_KEY, "Created profile Key");
        profile = addButton(R.string.profile, linearLayout);
        profile.setOnClickListener(this);
    }
    if (arguments.getBoolean(TO_ADD_FRIENDS_KEY)) {
        Log.i(LOG_KEY, "Created friends key");
        friends = addButton(R.string.friends, linearLayout);
        friends.setOnClickListener(this);
    }
    logout = addButton(R.string.logout, linearLayout);
    logout.setOnClickListener(this);

如果这不起作用,尝试检查是否有其他视图覆盖在您的按钮上,从而拦截了点击事件。

虽然我相信这会在以后对我有所帮助,但问题是onClick根本没有被调用。我在onClick的开头包含了一个日志语句,但它从未被调用过。据我所知,按钮根本没有接收到任何鼠标输入。感谢您帮我避免了一些麻烦。 - Mystik
我试了一下,按钮仍然完全不响应点击(没有颜色变化,没有通知,什么都没有)。 - Mystik

0

这可能是因为您的Activity主机没有实现IToolbarCallback。您需要使用类似以下代码进行检查:

@Override
public void onClick(View view) {
  Log.i(LOG_KEY, "A button was clicked.");

  if (getActivity() instanceof IToolbarCallback) {
    Log.i(LOG_KEY, "IToolbarCallback is implemented.");
  } else {
    Log.e(LOG_KEY, "No IToolbarCallback implemented!!!");
  }
}

不,它有。我仍然认为这不是分配OnClickListeners的问题,因为这些按钮不像普通按钮一样运作(即使没有分配侦听器,点击时也不会发生颜色变化,而对于按钮来说应该会发生)。 - Mystik

0
问题在于您没有为按钮设置任何id。因此,在这种情况下,所有按钮都具有相同的id。您必须显式地为每个按钮设置唯一的id。
 private Button addButton(int stringID,int id, LinearLayout linearLayout) {
    Button button = new Button(this);
    button.setText(stringID);
    button.setId(id);
    button.setOnClickListener(this);
    linearLayout.addView(button);
    return button;
}

然后为每个按钮添加一个ID。请记住,ID应该是唯一的,并且必须是正整数int。或者您可以直接使用view.generateViewId();

feed = addButton(R.string.feed,1, linearLayout);
profile = addButton(R.string.profile,2, linearLayout);
friends = addButton(R.string.friends,3, linearLayout);
logout = addButton(R.string.logout, 4,linearLayout);

然后将您的onClick()修改如下

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case feed.getId():
            itc.feed();
            break;
        case profile.getId():
            itc.profile();
            break;
        case friends.getId():
            itc.friends();
            break;
        case logout.getId():
            itc.logout();
            break;
        default:
            break;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接