Кнопки Android не могут быть нажаты - PullRequest
0 голосов
/ 29 апреля 2018

Я создаю приложение, которое использует Toolbar как fragment вверху с несколькими кнопками. Кнопки добавляются программно.

Проблема в том, что при запуске приложения появляются панель инструментов и кнопки, но кнопки не могут быть нажаты. Когда кнопки наведены (я использую эмулятор) или нажали, они вообще не меняются и не уведомляют мой 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 настроен правильно, кнопки просто сломаны на каком-то фундаментальном уровне.

Сюжет утолщен. Использование точно таких же настроек в других действиях, кажется, заставляет его работать нормально ... Насколько я могу сказать, никаких изменений не было.

Несмотря на это, я решил просто жестко запрограммировать его для этого действия, чтобы я мог перейти к другим частям приложения. Спасибо всем за рассмотрение проблемы. Я отправлю еще раз, если когда-нибудь выясню, что случилось.

Ответы [ 3 ]

0 голосов
/ 29 апреля 2018

Вероятно, это связано с тем, что на вашем хосте 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!!!");
  }
}
0 голосов
/ 29 апреля 2018

Проблема в том, что вы не установили 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 для каждой кнопки. Имейте в виду, что идентификатор должен быть уникальным и должен быть положительным 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;
    }
}
0 голосов
/ 29 апреля 2018

Не сравнивайте представления, чтобы увидеть, равны ли они, сравните идентификаторы. Здесь:

@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();
        }
    }
}

Более того, когда вы сами создаете представления, вам также необходимо указать их идентификаторы. Если у вас уровень API 17+, вы можете просто позвонить generateViewId() в представлении, и Android создаст для вас уникальный идентификатор. Так что сделайте это так:

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;
}

EDIT: Ваш код выглядит нормально, кроме того, что я указал выше. Одна вещь, которую я бы попробовал, это установить слушателя вне вашего метода 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);

Если это не сработает, попробуйте проверить, нет ли другого вида поверх ваших кнопок, который перехватывает события нажатия.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...