I am creating an app which uses a Toolbar like fragment at the top with a few buttons. The buttons are added programmatically.
The problem is that when I launch the app, the toolbar and buttons appear, but the buttons can't be clicked. When the buttons are moused over (I use an emulator), or clicked, they don't change at all, and don't notify my OnClickListener. However, the buttons and other components in the Fragment below it work perfectly.
The Toolbar's code:
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();
}
}
}
}
There's no other code pertinent to this, besides the callback interface.
public interface IToolbarCallback {
void feed();
void profile();
void logout();
void friends();
}
This is just used to let the host activity know what was clicked. Finally, the 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">
I use a builder for the fragment, and here's the code:
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();
}
}
Just to clarify, the buttons are receiving no inputs as far as I can tell. They aren't just failing to call onClick, they're failing to react in any way at all. As far as I know, onClick is set up correctly, the buttons are just broken on some fundamental level.
The plot has thickened. Using the exact same setups in other activities seems to make it work fine... As far as I can tell, there is were no changes.
Regardless, I decided just to hard code it for this activity so I could move on to other parts of the app. Thank you all for the consideration of the problem. I'll post again should I ever figure out what happened.
Don't compare views to see if their equal, compare ids. Here:
@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();
}
}
}
It should be:
@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();
}
}
}
Moreover, as you're creating the views yourself you need to also give them ids. If you're on API level 17+ you can simply call generateViewId() on the view and Android will create an unique id for you.
So do it like this:
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: Your code seem fine, apart from what I've specified above. One thing I would try is setting the listener outside your addButton method:
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);
If that doesn't work, try to check if there isn't any other view on top of your buttons that's intercepting the click events.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With