How to provide all ContextMenu logic in a separate class? - java

I am trying to put all my ContextMenu logic in a separate class but it seems like I am not able to recognize in this class whether someone selects a item.
I have an application with a main activity. Next to some other things this activity contains a listview. This listview should contain a context menu, so I defined it corresponding to its Clicklistener:
MyListener myListener = new MyListener();
listview.setOnItemClickListener(myListener);
listview.setOnCreateContextMenuListener(myListener);
MyListener implements both OnItemClickListener and OnCreateContextMenuListener. I did this to keep the class readable (like mentioned before there are already some other UI components and some logic). To this point everything works like a charm. Single clicks are recognized and also the ConextMenu is shown.
Now I also want that MyListener also reacts to the item that is selected inside the ContextMenu. Unfortunately only Activities and their corresponding SubClasses seem to provide a method like onContextItemSelected(menuItem item). So I would have to put that logic into my main activity and distribute my ContextMenu logic by doing this (I also tested this, it works, but distributing the logic seems to me like a no-go).
Do I miss here something? Is there a way to define some kind of a ContextMenu ClickListener for my listview in another way than putting it in my main activity? Or am I doing some bad practise without recognizing?
Looking forward to your opinions!
Cheers Eyeless

A quick and easy solution is to forward the clicks to your MyListener class.
Create a new method in your MyListener class. Ideally I would call it just like the original method:
public boolean onContextItemSelected(MenuItem item)
In this method you implement your logic.
Then make your MyListener variable a field of your Activity.
Now, just override onContextItemSelected(MenuItem item) in your Activity and forward the clicks to your listener class:
#Override
public boolean onContextItemSelected( MenuItem item ) {
return myListener.onContextItemSelected( item );
}

Related

Fragment is invisible but its views could be clicked

I am trying to enable user to go to a new Fragment when a list item is clicked. That's OK. I created an interface which allows me to handle click events from my FragmentA.java class. FragmentA is attached to my activity when activity started. my activity extends FragmentActivity.
In my activity class:
#Override
protected void onCreate(Bundle savedInsantaceState){
//...
getSupportFragmentManager().beginTransaction().replace(R.id.container, FragmentA.newInstance(param1, param2)).commit();
}
And then in FragmentA.java, i set that to my RecyclerView Adapter as click handler. I use add() method instead of replace() method to change the fragment, because i want to save the FragmentA's state (like RecyclerView position etc.) when FragmentB is attached.
private void setListeners(){
mAdapter.setOnItemClickListener(itemClickListener);
}
private ItemListAdapter.ItemClickListener itemClickListener = new ItemListAdapter.ItemClickListener() {
#Override
public void onItemClicked(View v, ItemModel item) {
FragmentManager manager =((FragmentActivity)mActivity).getSupportFragmentManager();
manager.beginTransaction().add(R.id.post_activity_layout_container, FragmentB.newInstance(item, param2, param3)).addToBackStack("comment").commit();
}
};
HERE IS THE ISSUE : In this case, FragmentA is running but invisible, while user sees FragmentB. User can reach views of FragmentA, and that cause problems. I wanna save the last state of FragmentA but user should not click on views of FragmentA from FragmentB. How to handle that issue? Is there a better practice to accomplish saving the last state?
EDIT
FragmentA contains some sorting, filtering. When i use replace() method, all filters that user set is invalidated, and also RecyclerView position became 0. Imagine that user is looking at (for example) 33. item in the list, clicks on it, FragmentB is attached, then go back to FragmentA. I want user to continue from 33. item, don't want user to try to find for where he was.
I'm not sure what you mean by "I wanna save the last state of FragmentA" exactly, but, AFAIK, the fact that you replace Fragments in a container doesn't mean they lose state. For example, you can still click on back button and this will revert the transaction, bringing the previous Fragment from the back-stack.
Edit: the effects that you observe are most probably caused by the destruction and re-creation of Fragment's View hierarchy. There are couple of approaches around it. The first one would be to store UIs state and restore it after re-initialization of the Fragment. Unfortunately, it might be tricky with RecyclerView position (you can google it). Another simpler approach (which is a hack) is to create the root View in onCreateView only once, keep a reference to it inside Fragment and return the same View on subsequent calls to onCreateView. If you decide to use the later approach, be careful because you'll be using Fragments not exactly the way there were intended to use.
Not directly related to your question, but I absolutely recommend avoiding manual Fragments management. It'll be too painful. You can use the official Navigation Component, or, alternatively, a simpler solution like FragNav library. I wrote this post about the later and it might help you.

Java Using Method from Different Class for Android

I'm very new to Java and OOP. Here is what I've got:
public class AmountChanged implements View.OnFocusChangeListener {
#Override
public void notFocused(View edittext1, boolean focused) {
//Do this awesome stuff
}
How do I instantiate and use this on one of my editText boxes in the mainActivity? I have already declared the editText boxes in the onCreate method.
In your class where you are writing the code for the editext,in that activity's onCreate() method, you need to write
yourEditext.setOnFocusChangeListener(new AmountChanged());
Also give an eye to this please as you can use anonymous classes too.
Let's imagine you created an EditBox:
EditText editText = new EditText(this);
To set focus change listener, you should provide OnFocusChangeListener instance to the setOnFocusChangeListener. Since AmountChanged implements OnFocusChangeListener, you can do the following:
editText.setOnFocusChangeListener(new AmountChanged());
If you are going to use the same listener on many EditText items, you can save this listener as a variable somewhere:
View.OnFocusChangeListener myListener = new AmountChanged();
...
editText.setOnFocusChangeListener(myListener);
In the onCreate method where you have the editText box(es) you want to use this with,
View.OnFocusChangeListener ac = new AmountChanged();
editText.setOnFocusChangeListener(ac);
From the View Android Developer Guide,
Set up listeners: Views allow clients to set listeners that will be notified when something interesting happens to the view. For example, all views will let you set a listener to be notified when the view gains or loses focus. You can register such a listener using setOnFocusChangeListener(View.OnFocusChangeListener). Other view subclasses offer more specialized listeners. For example, a Button exposes a listener to notify clients when the button is clicked.
Listener in android means that it is gonna listen to some event(OnTouchListener, OnClickListener, OnFocusChangedListener etc.). As you see OnFocusChangedListener interface is announced inside View class, in scope of Android it usually means that any child of View can produce this event, so you need to "listen" to those events.
In scope of EdiText what you have to do is something like this:
editText.setOnFocusChangedListener(new AmmountChanged());
EdiText is a child of View. So we are start "listening" to all OnFocusChanged events that will happen inside editText by registering our instance implementation OnFocusChangeListener.

When is Activity.onBackPressed called in Android? (in relation to other callback functions)

When is Activity.onBackPressed called in my Android application? I'm not looking for the obvious answer of when the user presses the back button. I wan't the answer in relation to other "callback" functions.
Is is possible to be called during the execution of another function within the Activity class?
What is the case if I have my Activity class implement some typical interfaces used for your typical game? For example GLSurfaceView.Rendered? I'm having the feeling onBackPressed is called during GlSurfaceView.Renderer.onDrawFrame but I'm not 100 % sure yet. Even if this isn't the case, I want to know how it works. (It seems difficult to find this kind of simple information anywhere.)
Finally, below is a code example for the layout of my Activity class. The question is, however, not limited to this particular setup.
class MainActivity extends Activity implements Renderer {
onCreate(...) {
layout = new FrameLayout(this);
GLSurfaceHolder glsurface = new GLSurfaceHolder(this, this);
glsurface.setRenderer(this);
layout.addView(glsurface);
setContentView(layout);
GLSurfaceHolder is just a simple dummy class that extends GLSurfaceView. It has the onTouchEvent overloaded and simple passes the data over to the MainActivity class. (The design philosophy in this very, very simple app is just to focus all the sensory and other data to one place and then "make things happen"..)
onbackpressed will be called when you pressed back button. Default behaviour will be destroying the activity. To avoid override the onbackkeypressed or onkeypressed.

Implementing option menu one time for several activities

I am trying to implement an options menu for my app and the same menu is used in different activities. In the Android developers site, it says the following:
Tip: If your application contains multiple activities and some of them
provide the same options menu, consider creating an activity that
implements nothing except the onCreateOptionsMenu() and
onOptionsItemSelected() methods. Then extend this class for each
activity that should share the same options menu. This way, you can
manage one set of code for handling menu actions and each descendant
class inherits the menu behaviors. If you want to add menu items to
one of the descendant activities, override onCreateOptionsMenu() in
that activity. Call super.onCreateOptionsMenu(menu) so the original
menu items are created, then add new menu items with menu.add(). You
can also override the super class's behavior for individual menu
items.
My activities extend from Activity, ListActivity or MapActivity, so what would be the correct way to implement what they are suggesting here? is it possible? Because I cannot extend this new class for all of these, I could only do something like public abstract BaseMenu extends Activity (as explained in this question) but this doesn't work for me. So I am wondering if there is a work around I can implement.
Thanks in advance
For that common Base menu class you need to extend MapActivity class . So you can extend that common base menu class for you all activities.
For that ListActivity you can also implement the list without ListActivity, you can implement it by only Activity or MapActivity.
you have to declare you listview in xml file with the id like below.
<ListView
android:id="#+id/listView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
Then you have to declare it in your activity class .
ListView listView = (ListView)findViewById(R.id.listView);
listView.setAdapter(your adapter);
Like above you can implement it without extend ListActivity.
you cannot use mapview without extending mapactivity class.... refer this..
MapView without MapActivity ..so you should let your base class extend map activity... and for activity using listview.. put listview in xml and you can use it in your activity..
I would create a static MenuProvider class that implements your onCreateOptionsMenu() and onOptionItemsSelected() methods statically to be called from onCreateOptionsMenu() and onOptionsItemsSelected() of the activities, like so:
public static class MenuProvider {
// You can pass it the activity and other variables used by this method if
// you need to.
// Since the implementation is the same across all activities, they should
// pass the same variables.
public static void onCreateOptionsMenu(MenuItem item, Activity callingActivity, ...)
... // Do stuff on create
}
public static void onOptionItemsSelected(MenuItem item, Activity callingActivity, ...)
... // Do stuff on item select
}
}
And in each of your activities, you would do:
public class MyMapActivity extends MapActivity {
...
public void onCreateOptionsMenu(MenuItem item)
MenuProvider.onCreateOptionsMenu(item, this, ... /*other variables */);
}
public static void onOptionItemsSelected(MenuItem item)
MenuProvider.onOptionItemsSelected(item, this, ... /*other variables */);
}
...
}

what does hashandlers mean in gwt

I am unable to understand the meaning of Has****Handlers interfaces in GWT. What would be the difference if a class implements HasClickHandlers (addClickHandler) and ClickHandler (onClick) interfaces.
thank you
HasClickHandlers - something that can be clicked, e.g. a button
ClickHandler - some code that handles on a click
A HasClickHandlers object is a widget, like a button, that can react when the user clicks on it. But a button by itself does not know what should happen when a user clicks on it. A developer can craft a ClickHandler object, which is some code that implements what should happen when the user clicks on that button. A button can be given a ClickHandler to react to the user's click, i.e. the button can have/hold a click handler - HasClickHandlers.
One may ask why does GWT say applications should define view interfaces with method signatures like:
HasClickHandlers getSaveButton();
instead of simply
Button getSaveButton();
Google advocates decoupling the view from presenter. The presenter usually cares very little for all the functionality of a button - it usually only cares that the button is something that can take a click handler and use it. An interface like HasClickHandler has very few methods and is very easy to mock. Using a real button however will sometimes require initializing some or part of the whole UI framework and instantiating prerequisite context classes in order to create a button for testing.
By having the interface return HasClickHandler instead Button, the unit test code for the presenter can decouple completely from the complexity of the UI framework by simply mocking interfaces like HasClickHandler. This means simpler test scaffolding and very fast unit tests (since you don't have the overhead of initializing/interacting with a UI framework).
http://googletesting.blogspot.com/2009/08/tott-testing-gwt-without-gwttest.html
Edit
OP asks:
ok, e.g. if ABC class implements Hasclickhandlers and Clickhandler and then onClick and addClickHandler (which returns HandlerRegistration), it means that 1)it will act on click event thru onClick method and 2)will let any other class(es) know (who is implementing ClickHandler and used addClickHandler of ABC class to register the event) that click has just been occurred? right?
Your classes like ABC will not implement HasClickHandlers. Only GWT widgets like buttons implement HasClickHandlers. Google is simply providing the HasClickHandlers interface as an alternative way to declare variable references to some widgets like buttons. These widgets will notify registered ClickHandler about a button click.
Your class ABC may implement ClickHandler or may contain an inner (possible anonymous) class that derives from ClickHandler. A typical usage looks like:
public class ABC {
...
getSaveButton().addClickHandler(
new ClickHandler() {
public void onClick(ClickEvent event) {
saveToDatabase();
}
}
}
...
The HasClickHandlers is for objects that generate click events. The ClickHandler is for objects that deal with the events.
For example, a Button will generate a click event. When you want to handle a click event, you create a ClickHandler that contains the code that does so. You register this ClickHandler with the Button object so that when a click happens, the Button knows who to tell about it. The HasClickHandlers interface is implemented by Button (via the FocusWidget parent class) which is just the interface for registering ClickHandlers. This interface simply standardizes the registering of ClickHandlers.

Categories