Android orientation change removes actionbar tab custom view - android

I have created ActionBar tabs with custom views. I am using a custom view because I want to show unread badge counts inside the tabs. When the activity is created, they appear just fine.
When I change the orientation of the device, the selected tab's custom view is removed from the tab.
This does not occur when I am using a tablet, just a phone. Does anyone know what could be causing this?
Here is the custom view I am using
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/ivTabIcon"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="0dp"
android:layout_centerInParent="true"
android:src="#drawable/ic_action_messages" />
<TextView
android:id="#+id/tvBadgeCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="#id/ivTabIcon"
android:layout_alignTop="#id/ivTabIcon"
android:layout_marginRight="0dp"
android:layout_marginTop="3dp"
android:background="#drawable/background_message_notification"
android:gravity="center"
android:minWidth="17sp"
android:paddingBottom="1dp"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:text="#null"
android:textColor="#color/white"
android:textSize="12sp" />
</RelativeLayout>
Here is the code when I inflate the custom views
RelativeLayout messageView = (RelativeLayout) LayoutInflater.from(this).inflate(R.layout.tab_message, null);
ImageView messageIcon = (ImageView) inboxView.findViewById(R.id.ivTabIcon);
messageIcon.setImageResource(R.drawable.ic_action_messages);
TextView tabBadgeInbox = (TextView) inboxView.findViewById(R.id.tvBadgeCount);
actionBar.newTab().setCustomView(messageView);
UPDATE
Here is the screen shot of the ActionBar when the activity is created
And when I change orientation here is what the ActionBar looks like
Now if I create the Activity in landscape mode, the ActionBar loads properly

Related

unable to setText of button in customized navigational drawer

I have made a customised navigational drawer with 3 buttons and I want to change text on the buttons according to the activity they are associated with. So when I made a java object of the layout of navigational drawer using LayoutInflater and got handle of each button using findViewById on that layout object, I set Text of each button but when i am running the app the text does not appear(in XML I have not set any text for the buttons). Rest all is working fine.
<FrameLayout 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"
android:id="#+id/drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.sahil.childcare.NavigationalDrawerFragment">
<RelativeLayout
android:layout_height="wrap_content"
android:layout_width="match_parent">
<include
layout="#layout/nav_profile"
android:id="#+id/nav_profile"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/nav_profile"
android:layout_marginLeft="-5dip"
android:layout_marginRight="-5dip"
android:layout_marginTop="-5dip"
android:layout_marginBottom="-5dip"
android:id="#+id/top_button"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/top_button"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginLeft="-5dip"
android:layout_marginRight="-5dip"
android:layout_marginTop="-7dip"
android:layout_marginBottom="-5dip"
android:id="#+id/middle_button" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/middle_button"
android:id="#+id/bottom_button"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginLeft="-5dip"
android:layout_marginRight="-5dip"
android:layout_marginTop="-7dip"
android:layout_marginBottom="-5dip"/>
</RelativeLayout>
</FrameLayout>
The part of the code in main activity(inside onCreate() method) involving this drawer is here
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.fragment_navigational_drawer,null);
Button topButton = (Button) view.findViewById(R.id.top_button);
Button middleButton = (Button) view.findViewById(R.id.middle_button);
Button bottomButton = (Button) view.findViewById(R.id.bottom_button);
topButton.setText("School");
topButton.setTextColor(getResources().getColor(R.color.red));
middleButton.setText("Teacher");
middleButton.setTextColor(getResources().getColor(R.color.red));
bottomButton.setText("Child");
bottomButton.setTextColor(getResources().getColor(R.color.red));
First thing I'd check if the buttons are even visible on screen.
To do that you can set them some color background, e.g.:
android:background="#ff0000"
and also use hierarchy-viewer to make sure your buttons appear where you expect them to appear.
Next thing to check is if the newly inflated fragment_navigational_drawer is actually being used for the Navigation Drawer, or maybe it's a different instance of this layout, to do that you can add some logging to the inflation code, printing the specific instance you put on screen, and verifying in hierarchy-viewer you see the right instance on screen.
UPDATE:
For completeness of the answer, per comments below, if you already added a layout via xml (e.g. using <include>), instead of inflating it in code:
View view = inflater.inflate(R.layout.fragment_navigational_drawer,null);
you need to get a handle of the already inflated layout, via something like:
View view = findViewById(R.id.my_navigational_drawer);

Android How to Create Custom ActionBar with custom up button and custom background image

I'm a beginner with Android. I want to create a custom actionbar for my app, with a custom background image and a custom up button, I have tried but result is not exactly like what I want.
My custom action bar I want my custom background fit to screen. How can I do?
This is my custombar_layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
android:background="#drawable/bar">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/back"
android:scaleType="fitStart"/>
<TextView
android:id="#+id/tv_title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:layout_gravity="center"
android:layout_marginLeft="?attr/actionBarSize"
android:layout_marginRight="?attr/actionBarSize"
android:text="SFlashCard"/>
</LinearLayout>
And in Main activity:
ActionBar actBar = getSupportActionBar();
actBar.setDisplayShowHomeEnabled(false);
actBar.setDisplayShowTitleEnabled(false);
LayoutInflater inflater = LayoutInflater.from(this);
View customView = inflater.inflate(R.layout.custom_actionbar, null);
actBar.setCustomView(customView);
actBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
actBar.setDisplayShowCustomEnabled(true);
Many thanks for all support!

TextView in custom ListView item view isn't filling parent in API 18 & 19

I have a custom list view adaptor that uses a customized list item view. The custom list item view has an image view on the left with a stack of two TextViews, a main title on top and subtitle below, to the right. What I want to happen is to have the subtitle disappear and the main text to fill the space if there is no subtext to display.
I've tested this against all other phone / tablet APIs between 16 and 23. Everything is working as expected EXCEPT when I run on a device running with Android 4.3.1 (API 18) Android 4.4.2 (API 19). Running against API 18 or 19, the subtitle view visibility does get set to View.GONE, but the main title view does not resize to occupy the space.
Does anyone know what's going on here?
Here's the layout file for the list item:
list_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical"
android:padding="5dp">
<ImageView
android:id="#+id/list_item_snapshot_imageview"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#color/medium_grey"
android:contentDescription="#string/item_snapshot" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignBottom="#id/list_item_snapshot_imageview"
android:layout_alignTop="#id/list_item_snapshot_imageview"
android:layout_marginLeft="5dp"
android:layout_marginStart="5dp"
android:layout_toEndOf="#id/list_item_snapshot_imageview"
android:layout_toRightOf="#id/list_item_snapshot_imageview"
android:orientation="vertical">
<TextView
android:id="#+id/list_item_title_textview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="20sp"
tools:text="Main Text" />
<TextView
android:id="#+id/list_item_subtitle_textview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="14sp"
tools:text="Subtext" />
</LinearLayout>
</RelativeLayout>
Here's the java code that is responsible for updating the content. viewHolder is just a static class containing references to the TextViews and is held in a tag on the list item for view recycling.
NamedItem item = getRowItem(section, position);
if (item != null) {
viewHolder.titleTextView.setText(item.getName());
if (item.getSubtitle() != null) {
String subtitle = ((ItemInfo) item).getSubtitle();
viewHolder.subtitleTextView.setText(subtitle);
viewHolder.subtitleTextView.setVisibility(View.VISIBLE);
} else {
viewHolder.subtitleTextView.setVisibility(View.GONE);
}
}
EDIT
I did some more testing and this also is happening on API 18 as well as 19. I changed the rest of the description to reflect that.
Figured this out. Looks like something about the way ListView item views are handled in API 18 & 19 doesn't like having RelativeLayout as the root layout in a custom ListView item. Wrapping the entire layout in a LinearLayout fixed the problem:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:padding="5dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Other Views ... -->
</RelativeLayout>
</LinearLayout>
Tried this after coming across this SO answer: https://stackoverflow.com/a/21334982/1777839
Still doesn't explain WHY this happens though.

inflating layout

I'd like to achieve such a layout, where user got 2 control panels. He is able to switch from first to second by pressing button and vice versa.
Already have tried to use LayoutInflater, however, without success :/
The main reason, why doing it with 2 different layouts is, that buttons will be almost on the same position, so i'd like to prevent all that mess in one layout and create 2 separate control panel layouts.
Here are my layouts:
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/control_panel_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="5">
<!-- Here comes including layouts-->
</RelativeLayout>
</LinearLayout>
control_panel_1.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/control_panel1"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/btn_action1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/ic_action_selector"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
<Button
android:id="#+id/btn_action2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/ic_action_selector2"
android:layout_centerVertical="true"
android:layout_toLeftOf="#+id/btn_action1"
android:layout_marginRight="50dp"/>
<Button
android:id="#+id/btn_action3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/ic_action_selector3"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/btn_action1"
android:layout_marginLeft="50dp" />
</RelativeLayout>
control_panel_2.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/control_panel1"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/btn_action3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/ic_action_selector4"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
<Button
android:id="#+id/btn_action4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/ic_action_selector5"
android:layout_centerVertical="true"
android:layout_toLeftOf="#+id/btn_action3"
android:layout_marginTop="20dp"
android:layout_marginRight="60dp"/>
</RelativeLayout>
MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_root);
RelativeLayout controlPanelLayout = (RelativeLayout) findViewById(R.id.control_panel_layout);
//Inflate first control panel on activity start
LayoutInflater layoutInflater = (LayoutInflater)
this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View controlPanel1 = layoutInflater.inflate(R.layout.control_panel_1.xml);
controlPanelLayout.addView(controlPanel1)
}
EDIT:
As shown in the image, let's say activity starts with Screen1 and once user press Btn1, Screen2 appears...as you can see, only control panel has been switched.
however, it won't inflate that layout at start of application...
Thanks in advance for any suggestions, hints...
Inflate your control panel in onCreateView() and when handling button click (to change panel). The code should be somewhat like this:
private void inflateYourPanel(int panelLayoutID, ViewGroup placeholder) {
placeholder.removeAllViews();
View view = LayoutInflater.from(mActivity).inflate(panelLayoutID, placeholder, false);
//find your views and set values and listeners
placeholder.addView(view);
}
Edit: placeholder may be any layout (control_panel_layout) inflated when starting activity etc
Still may be you'd better look at Fragments - it may fit your purpose better and provide more scalability

Android action bar with two stretched buttons

Does anybody know how to easily implement an action bar with two stretched buttons?
Here is an example of the Google calendar app:
Thank you!
If you rather have this in the ActionBar for whatever reason, one way to achieve this is by using a custom view on the Action bar. Within you Custom View's layout then worry about setting up the buttons width.
Telling the activity to use a custom view for the action bar:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ActionBar ab = getActionBar();
ab.setDisplayShowHomeEnabled(false);
ab.setDisplayShowTitleEnabled(false);
final LayoutInflater inflater = (LayoutInflater)getSystemService("layout_inflater");
View view = inflater.inflate(R.layout.action_bar_edit_mode,null);
ab.setCustomView(view);
ab.setDisplayShowCustomEnabled(true);
}
layout/action_bar_edit_mode.xml can then look something like:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="fill_horizontal"
android:orientation="horizontal" >
<LinearLayout
android:layout_alignParentLeft="true"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:id="#+id/action_bar_button_cancel"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="Cancel" />
<Button
android:id="#+id/action_bar_button_ok"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="Ok" />
</LinearLayout>
</RelativeLayout>
Hope it helps someone!
Note: I realize the ugly nesting layouts here and normally I wouldn't recommend this but for some reason the actionbar's own layout refuses to let the LinearLayout take up the entire width on its own. Normally you should avoid nesting layouts unnecessarily like this!
Perhaps if someone sees this they can point us to a better solution?
What it looks like:
EDIT: There is an excellent post by Roman Nurik where he explains a way to do this very nicely.
EDIT 2: If anyone is curious, the correct way to lay out the buttons so that they expand the width of the actionbar without the need to nest your layouts like I did above, is to set the custom view with the proper layout parameters that allows its component to match the parent group.
Essentially:
actionBar.setCustomView(view,new ActionBar.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
I know 2 ways to do this, but one doesn't stay on top.
Here is the 1st:
You need to override the method onCreateOptionsMenu, but this is add on the ActionBar, you need API 11 to do this and when you rotate the screen this buttons appear on ActionBar, this depends of the screen size.
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
MenuItem add = menu.add(Menu.NONE, ADD_TIME, 0, R.string.add_time);
add.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
MenuItem qkAdd = menu.add(Menu.NONE, QUICK_ADD_TIME, 1, R.string.quick_add_time);
qkAdd.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
}
and this is the result:
if you're using a Fragment you need to set setHasOptionsMenu to true, otherwise the menu wont show.
Here is the 2nd:
cancel_done.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/color_bar"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:dividerPadding="12dp"
android:orientation="vertical"
android:showDividers="end" >
<Button
android:id="#+id/button1"
style="#drawable/btn_cab_done_holo_light"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="#drawable/btn_cab_done_holo_light"
android:text="CANCEL"
android:textSize="14sp" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:dividerPadding="12dp"
android:orientation="vertical"
android:showDividers="beginning" >
<Button
android:id="#+id/button2"
style="#drawable/btn_cab_done_holo_light"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="#drawable/btn_cab_done_holo_light"
android:text="DONE"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
the resource style btn_cab_done_holo_light.xml you can find on ..\sdk\platforms\android-%%\data\res\drawable and then on your layout you just add:
<include
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_gravity="fill"
layout="#layout/cancel_done" />
and this is the result:
I don't now if is the best way, but it's working.
Make a horizontal LinearLayout with two buttons. Then set each of their widths to match_parent and android:layout_weight="0.5"
(Each button will then take up 50% of the space).
EDIT:
To apply as the ActionBar background:
(ActionBarSherlock) getSupportActionBar().setCustomView(R.layout.my_view);
(ActionBar) getActionBar().setCustomView(R.layout.my_view);
You can use the actionMode of the ActionBar to implement the Done and Cancel actions.
See http://developer.android.com/guide/topics/ui/menus.html#CAB
Is called done bar in android. have a look at this it will be helpfull
https://github.com/googlesamples/android-DoneBar

Categories

Resources