I'm learning actionviews and was following this short tutorial:
http://wptrafficanalyzer.in/blog/adding-custom-action-view-to-action-bar-in-android/
But I don't know why the EditText object becomes null at the runtime. Please help me with this.
MainActivity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
/** Create an option menu from res/menu/items.xml */
getMenuInflater().inflate(R.menu.items, menu);
/** Get the action view of the menu item whose id is search */
View v = (View) menu.findItem(R.id.search).getActionView();
/** Get the edit text from the action view */
EditText txtSearch = ( EditText ) v.findViewById(R.id.txt_search);
/** Setting an action listener */
txtSearch.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
Toast.makeText(getBaseContext(), "Search : " + v.getText(), Toast.LENGTH_SHORT).show();
return false;
}
});
return super.onCreateOptionsMenu(menu);
}
}
items.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/photo"
android:title="Photo"
app:showAsAction="ifRoom|withText"
/>
<item
android:id="#+id/video"
android:title="Video"
app:showAsAction="ifRoom|withText"
/>
<item
android:id="#+id/mobile"
android:title="Mobile"
app:showAsAction="ifRoom|withText"
/>
<item
android:id="#+id/search"
android:title="Search"
app:showAsAction="ifRoom|collapseActionView"
android:actionLayout="#layout/search_layout"
/>
</menu>
search_layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<EditText
android:id="#+id/txt_search"
android:inputType="text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</RelativeLayout>
In your comment you stated the xml file names are search_layout.xml and items.xml. Now, in your code, you'll notice this line:
setContentView(R.layout.activity_main);
And this is important, so listen up: This line of code basically says, here is the corresponding xml file (layout resource element) that belongs to this java class. Now, what is the point of this? Well, if you want to access something that is in the content of an xml file called hello, and change the image of an image button, you cant do it until you specify where that image button is.
XML: I'm what the screen looks like!
Java: I'm what to do with some screen. What screen? Well, that screen is described in the setContentView line.
So, as you go deeper into android, you will start to get more and more XML files, and you need to specify which one you are talking about, so that the java (which is the brain of your program) knows what to do and where to do it.
Hope this helped, let me know if it did!
Ruchir
Your setContentView(R.layout.activity_main); layout is referencing to the wrong file. Change to (i guess is that the name of the file) setContentView(R.layout.search_layout);
Related
I am trying to use icon fonts with ActionBar menu item using a custom layout. Applying a layout to the menu item does solve the problem and the icon font renders perfect but doing so make the menu item un-clickable. Is there a way to solve this?
I am trying to avoid using a custom action bar because I want to use font icons instead of images.
Here is my code so far:
layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="48dp"
android:layout_height="match_parent"
android:layout_gravity="right">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
style="#style/action_bar_icons"
android:text="#string/ic_sliders"
android:clickable="true"/>
</RelativeLayout>
menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.hackerrank.projectx.SearchResultsActivity">
<item
android:id="#+id/action_filters"
android:title="#string/action_filters"
android:showAsAction="always"
android:onClick="onFilterClick"
android:actionLayout="#layout/action_search_result_filter" />
<item
android:id="#+id/action_toggle_view"
android:title="#string/action_custom_view"
/>
</menu>
You Can setOnClickListener on the actionLayout something like this
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(mMenuResource, menu);
MenuItem item = menu.findItem(R.id.notfication);
FrameLayout badgeLayout = (FrameLayout) MenuItemCompat.getActionView(item);
badgeLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent not = new Intent(DrawerActivity.this,NotificationActivity.class);
not.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(not);
}
});
return super.onCreateOptionsMenu(menu);
}
If you are using it inside a fragment try this:
onCreateView()
{
setHasOptionMenu(true);
...`enter code here`
}
I'm trying to implement a notification icon in my actionbar to show the count of notifications. Something like
I've added a custom layout file for it NotificationIcon.xml:
<!-- Menu Item Image -->
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="2dp"
android:clickable="true"
android:src="#drawable/notification" />
<!-- Badge Count -->
<TextView
android:id="#+id/actionbar_notifcation_textview"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:minWidth="20dp"
android:layout_alignParentRight="true"
android:gravity="center_horizontal"
android:background="#drawable/circle_green"
android:fontFamily="sans-serif-black"
android:textStyle="bold"
android:text="0"
android:textColor="#FFFFFF" />
</RelativeLayout>
And used it in my menu as main_activity_actions.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/action_add"
android:title="#string/AddTag"
android:icon="#+drawable/ic_action_new"
android:showAsAction="always" />
<item
android:id="#+id/notification_icon"
android:title="#string/PendingJobs"
android:actionLayout="#layout/notificationIcon"
android:icon="#+drawable/notification"
android:showAsAction="always" />
<item
android:id="#+id/gps_status_icon"
android:title="#string/GPS"
android:icon="#+drawable/gps_grey"
android:showAsAction="always" />
</menu>
The UI looks fine but the OnOptionsItemSelected is not being called for the notification icon. It works fine for the other two.
I did google this and ound this link: onOptionsItemSelected not getting called when using custom action view
I tried to implement it in my main activity:
public override bool OnCreateOptionsMenu(IMenu menu)
{
actionBarMenu = menu;
MenuInflater.Inflate(Resource.Menu.main_activity_actions, menu);
var notificationMenuItem = menu.FindItem(Resource.Id.notification_icon);
notificationMenuItem.ActionView.Click += (sender, args) => {
this.OnOptionsItemSelected(notificationMenuItem);
};
return base.OnCreateOptionsMenu(menu);
}
but it does not works for me. It never fires the click event.
Please help.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getSupportMenuInflater();
inflater.inflate(R.menu.main_activity_actions, menu);
final View notification_icon= menu.findItem(R.id.notification_icon).getActionView();
notification_icon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// write ur code here
}
});
return super.onCreateOptionsMenu(menu);
}
use this code......hope it helps :)
i struggle with the same Problem and found following Solution:
First of all: i really don't know why but if you delete the
android:clickable="true"
then ... and ONLY then you get the click event!!!
Second: you have to set the Listener...
...
item.getActionView().setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Do Your Stuff.....
}
});
May someone can Explain why this is with the "android:clickable" Thing... i tough the standard value IS true??
You had made ImageButton clickable, and then written the clickListener for the Layout of menuItem. You can observe that if you click outside the ImageButton but inside the MenuItem layout, your listener will work. The reason is simple clickListener for ImageButton has nothing to do, on setting Clickable = true defines whether this button reacts to click events. Just simply set Clickable = false, your button will not react to its click event, eventually your whole layout will react to your defined clickListener and then your problem will be solved.
I need to know how can I change actionbar searchview icon when click on it? I'm currently using "Theme.Holo.Light" and I don't want to change this theme anymore. Is there anyway can change SearchView icon in ActionBar when click on it?
yes it is possible to do.
What you should do is create custom layout for the search menu option let say searchLayout.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:orientation="vertical" >
<ImageView
android:id="#+id/img_search"
android:layout_width="40dip"
android:layout_height="40dip" />
</LinearLayout>
now use this layout in your menu option.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/menuSearch"
android:actionLayout="#layout/searchLayout"
android:showAsAction="always"
android:title="search"/>
</menu>
now you just have to get the view from the menu option :
#Override
public boolean onPrepareOptionsMenu( Menu menu )
{
final MenuItem item = menu.findItem( R.id.menuSearch );
LinearLayout layoutSearchView = (LinearLayout) item.getActionView();
ImageView img = (ImageView) layoutSearchView.findViewById( R.id. img_search);
// now you have your image of search . on click you can change the image using set onclick listener of image or do what ever you want with the layout.
img.setOnClickListener( new View.OnClickListener()
{
#Override
public void onClick( View v )
{
// change your image
}
} );
}
sorry for any typo.
Hope this will help.
Note : I am doing change image code in onPrepareOptionsMenu in this snippet but I suggest to create a method and pass the menu item from onPrepareOptionsMenu and do the task in that method.
I'm new to Android programming and probably I don;t understand Java very well yet, so i got this problem with my program.
Every time I press button on my menu I get the java.lang.NullPointerException.
Is there any way to reference to this TextView object and change its text when item2 on menu is clicked?
public class MainActivity extends Activity {
TextView tv;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MainActivity.this.tv = (TextView) findViewById(R.id.tekst1);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.mymenu, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.item2) {
MainActivity.this.tv.setText("aaa");
}
return super.onOptionsItemSelected(item);
}
}
EDIT:
mymenu xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/item1"
android:icon="#android:drawable/ic_menu_week"
android:title="Option 1"/>
<item
android:id="#+id/item2"
android:icon="#android:drawable/ic_menu_month"
android:title="Option 2"/>
</menu>
activity_main.xml
<RelativeLayout 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" >
<TextView
android:id="#+id/tekst1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="#string/hello_world"
tools:context=".MainActivity" />
</RelativeLayout>
You need to load the layout BEFORE retrieving the element.
Just replace
MainActivity.this.tv = (TextView) findViewById(R.id.tekst1);
setContentView(R.layout.activity_main);
By
setContentView(R.layout.activity_main);
MainActivity.this.tv = (TextView) findViewById(R.id.tekst1);
The findViewById method tries to find an element (from an ID) inside the hierarchy of the view. That's why you need to load this hierarchy (from the XML file) before! Otherwise you search in an empty hierarchy of views
You have to change your onCreate method to this:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MainActivity.this.tv = (TextView) findViewById(R.id.tekst1);
}
You have to reference your views after doing setContentView for your Activty.
By using the setContentView(int layoutResId) method android platform is creating all the view objects contained in your layout xml file provided to the setContentView(int layoutResId) method. This means that before the setContentView(int layoutResId) method is called the findViewById(int resId) method will return null for any view references in the layout, causing some potential NullpointerExceptions. To avoid these errors it's a good habit to place the setContentView(int layoutResId) method call at the very top of the onCreate() method.
Check this out : http://www.jayway.com/2009/03/26/layout-resources-in-android/
I've been trying to use the setActionView from the ActionBar in ICS
Seems like it should be straight forward but somehow I'm not getting the layout alignment that I would hope for. As you can see in the image below the 'target' icon is centered correctly within it's layout. But when I setActionBar(progress) the progress view is always aligned to the right whatever I try.
Here are the 2 states, before and after clicking the menu item. As you can see the progress view is always aligned to the right. I've tried changing the gravity options in the my progress layout xml from left to right to center and whatever I do change it doesn't seem to change anything.
I haven't found any info regarding this problem so I'm thinking I must be doing something wrong.
Do anyone have a clue?
Thanks for the help!
Here's my action bar menu layout 'action_bar_menu.xml'
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/locate"
android:title="locate"
android:icon="#drawable/locate"
android:showAsAction="ifRoom|withText" />
</menu>
Here's my progressbar layout 'inderterminate_progress.xml'
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<ProgressBar android:layout_width="25dp"
android:layout_height="25dp"
android:layout_gravity="center"
android:indeterminate="true"
style="?android:attr/progressBarStyleInverse"/>
</FrameLayout>
And finally here's my testx Activity
public class HelloAndroidActivity extends Activity {
/**
* Called when the activity is first created.
* #param savedInstanceState If the activity is being re-initialized after
* previously being shut down then this Bundle contains the data it most
* recently supplied in onSaveInstanceState(Bundle). <b>Note: Otherwise it is null.</b>
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
getActionBar().setTitle("Test");
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.action_bar_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
if (R.id.locate == item.getItemId()) {
final MenuItem menuItem = item.setActionView(R.layout.inderterminate_progress);
new Thread(new Runnable() {
#Override
public void run() {
SystemClock.sleep(3000);
runOnUiThread(new Runnable() {
#Override
public void run() {
menuItem.setActionView(null);
}
});
}
}).start();
}
return true;
}
}
It seems that explicitly defining the style and adding a 4dip padding in the root of the layout to inflate as shown below solves this issue
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingLeft="4dip"
android:paddingRight="4dip"
style="?android:attr/actionButtonStyle" />
This seems to be used in the android stylesheet here
A little late but the right solution is not an absolute value such as 4dp. The right approach is to set the minWidth to ABS values:
android:minWidth="#dimen/abs__action_button_min_width"
Example progress bar:
<?xml version="1.0" encoding="utf-8"?>
<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="#dimen/abs__action_button_min_width"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true"
android:layout_gravity="center"
style="#android:style/Widget.ProgressBar.Small"/>