master/detail template with action menu - right way to show both - android

Beginner here, targetting sdk v14 and v17 for my learning...no need for older support.
I am using the master/detail template and trying to get an action menu (for SEARCH) to show up both in phone and tablet view. Actually I can get it to work, but I have to duplicate up my code in both ItemDetailActivity.java and ItemListActivity.java
These are the methods that I have to have in both for SEARCH to work:
public boolean onQueryTextChange(String newText) {
public boolean onQueryTextSubmit (String query) {
public boolean onClose () {
I only want to search the "detail", not the "list".
So my question: is there a way to associate the action bar with only the list fragment? That way I can keep the search functions in 1 file.
Thanks!

I'll go ahead and answer what I (think) I know as I don't want to leave this question open.
From tracing in the debugger, it looks to me like the phone activity and the tablet activity are separate and if you want to hook up an actionmenu, you have to hook it up to both separately.

Related

Why does findViewById(R.android.id.home) always return null?

I'm using AppCompat and trying to recall the ImageView for the up/back button belonging to the toolbar.
I know R.android.id.home exists, because I can manage its click as a Menu item:
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
//this works
}
return super.onOptionsItemSelected(item);
}
Apart from that, whenever I try to call findViewById(android.R.id.home) - be it onCreate, be it onClick of a custom button - I get null.
I even get null if, in the sample above, I call findViewById(item.getItemId()).
Why is it?
This question has been asked before here, most times regarding ActionBarSherlock (which I am not using). Another time it was suggested to use:
getWindow().getDecorView().findViewById(android.R.id.home)
But it isn't working. In that question the OP also says findViewById(android.R.id.home) works on API>3.0, but that's not true for me. Any ideas?
Whether or not the "home" icon is a widget, and what class of widget it is, and what its ID is (if any), is up to the implementation of the action bar. The native action bar may do this differently for different API levels, and all of that may be different than the way appcompat-v7 does it. Let alone ActionBarSherlock or other action bar implementations.
Specifically, android.R.id.home is a menu ID, which is why you can use it in places like onOptionsItemSelected(). It is not necessarily a widget ID, which is why it may or may not work with findViewById().
Ideally, you do not attempt to mess with the internal implementation of a UI that you did not construct yourself.
do one really has to make his own Up button to style it?
I do not know, as I have never tried to style it.
As CommonsWare said android.R.id.home is a menu ID, not a widget ID. But if you want to access this home button you could do it. For example I needed it to highlight home button in in-app tutorial:
fun AppCompatActivity.getToolbarHomeIcon(): View? =
this.findViewById<Toolbar?>(R.id.toolbar)?.let { toolbar ->
val contentDescription: CharSequence = toolbar.navigationContentDescription.let {
if (it.isNullOrEmpty()) {
this.getString(R.string.abc_action_bar_up_description)
} else {
it
}
}
// Here home button should be created even if it doesn't exist before
toolbar.navigationContentDescription = contentDescription
ArrayList<View>().let { potentialViews ->
toolbar.findViewsWithText(
potentialViews,
contentDescription,
View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION
)
potentialViews.getOrNull(0)
}
}

Actionbar navigation

My android application targets the latest platform. I am new to the platform, and read bit conflicting information on actionbar. The way I was using it for navigation was.
menu.xml
<menu>
<item android:id="#+id/action_sort_size"
android:icon="#android:drawable/ic_menu_sort_by_size"
android:title="#string/action_barabc"
android:onClick="abc" />
<item android:id="#+id/action_sort_alpha"
....
In my activity
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void abc(MenuItem item) {
//...
}
this works, but the back/up navigation is not working correctly. could be unrelated, still like to confirm.
But, I also see implementation like here
where it switches on item.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menuitem1:
Toast.makeText(this, "Menu Item 1 selected", Toast.LENGTH_SHORT)
.show();
break;
case R.id.menuitem2:
....
}
Which is the better approach?
The better approach, in my opinion, is the switch approach. There aren't many reasons why, but I'll list them:
The code is centralized. You don't have x amount of methods that basically do the same thing. It keeps your code more readable; it is "cleaner". You also get a default statement using the switch, this can help if you mess up and forget to make a case specifically for an element in the layout.
If you really wanted to have a centralized method using xml, you would have onClick reference the same method and check the ids of the View parameter. Which is essentially the same asonOptionsItemSelected.
It is a part of the API. The Android engineers would not have made it a part of the API if they didn't want the developer to use it. Yes the XML is techinally API, but XML should be used more for layouts and visuals, not for logic.
Everyone uses it. All the tutorials I have seen and everyone's code uses this method. It is now more of a convention.
It's largely personal, but if it looks like it's a convention, and everyone uses it, I'd adhere to it. Especially if you're working as part of a team. Different coding styles for such arbritrary things should be avoided.
And concerning your back/up navigation, it shouldn't make a difference which way you do it, since you have to implement the same code to get that navigation type.

How to use onSearchRequested() to disable Search button globally?

I posted a similar question: Android - How to disable Search button, how to implement onSearchRequested()? But at that time I was not very sure what I was looking for. But this time I'll be very specific.
What I am NOT looking for is: How I can use the dialog builder to disable the search button. This has been answered.
What I AM looking for is: How can I use the onSearchRequested() method to permanently disable the search button. Please take a look here http://www.youtube.com/watch?v=9lekcH1JAf0&feature=youtu.be for further elaboration.
In regards to this method, google states the following: "You can override this function to force global search, e.g. in response to a dedicated search key, or to block search entirely (by simply returning false)". Here is the link: http://developer.android.com/reference/android/app/Activity.html#onSearchRequested%28%29
#Override
public boolean onSearchRequested() {
return true;//block search
}
if is not working have you tried this solution?:
https://stackoverflow.com/a/5461709/1552551

Add/change compatibility SimpleMenu/MenuItem from compatibility Fragment

I realise this is a specific problem however I feel like others who are dealing with compatibility must have dealt with this.
As the user swipes through various fragments in the ViewPager I would also like the actionBar menu items to change. I am not sure if this is easily doable for the compatibility actionbar, any direction or help would be extremely appreciated. I am changing the title simply via setTitle() since the ActionBarHelper handles this however i cant find anything for updating the menu items. I tried the following but it fails..
public void setMenuDynamically(int resId){
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(resId, menu);
}
Looking through the code it seems there should be an easy/obvious way to get a handle to the SimpleMenu and add an item and set its icon.
Thanks in advance ( I am hoping the google boys are reading this as the android developers Google+ suggests)
Ok well please let me know if I suck as describing things or if there just is not much knowledge on this topic. If the first I am really sorry guys. Regardless I seemed to get this to work but am unsure if this is the correct way.
AcitonBarHelper
public void updateMenu(MenuItem item) {
}
ActionBarHelperBase (for 2.2 - 3.0 devices )
#Override
public void updateMenu(MenuItem item){
addActionItemCompatFromMenuItem(item);
}
And create similar methods for honeycomb and ICS
finally i have a listener for page changing and in that listener i call...
public void setMenuDynamically(int resId, String title){
MenuItem item = menu.add(title);
item.setIcon(resId);
getActionBarHelper().updateMenu(item);
MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
}
I am not sure if the MenuItemCompat is necessary but I included it nonetheless. Everything seems to work great for 2.2 at least. I will most likely have to make changes in the Overrides but I can handle myself from here.

Getting selected text in a WebView via a contextual action bar

It's known to be difficult to get selected text in a WebView because WebView text selection is actually handled by a private class, WebTextView.
However, with the recently released Android 4.0 Design guidelines, there seems to be a glimmer of hope of achieving this through contextual action bars (CABs). It says:
Use CABs whenever you allow the user to select data via long press. You can control the action content of a CAB in order to insert the actions you would like the user to be able to perform.
Am I misinterpreting this? Is there a way to retrieve selected text from a WebView via a CAB?
After a long click and text selection mode begins, I can currently detect when the ActionMode starts and modify the original copy/paste Menu; however, I can't quite figure out how to actually retrieve the selected text.
You can't do that yet with the current API.
I filed a feature request for this - Issue 24841: WebView should allow applications to supply a custom Contextual Action Bar http://code.google.com/p/android/issues/detail?id=24841
Basically, WebView in 4.0 has hardcoded its own Contextual Action Bar (CAB). That CAB has a reference back to the WebView and with that reference, it can get the selected text. I'm not sure how you were able to detect the ActionMode starting and modify the menu, but if you were able to do all of that, then you are stuck because getSelection() is package-private currently. I filed that as a separate issue and linked it to the previous issue above.
You can use javascript to get the selected text: window.getSelection(), and use WebView's addJavascriptInterface function to return the result.
thanks for your information, I have solved a hard issue..
I just want to add some function into the actionmode.
The following is my code, May be helpful to others.
#Override
public ActionMode onWindowStartingActionMode(Callback callback) {
// TODO Auto-generated method stub
ActionMode mode = super.onWindowStartingActionMode(callback);
mode.getMenuInflater().inflate(R.menu.actions, mode.getMenu());
mode.getMenu().findItem(R.id.action_add).setOnMenuItemClickListener(new OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
// TODO Auto-generated method stub
Log.i("", "onMenuItemClick add ");
return false;
}
});
return mode;
}

Categories

Resources