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);
Related
i had gone through research about for couple of days but didn't get it resolved. Problem in this Question is similar to mine but I couldn't solve my issue using this either.
I had tried to get the circular reveal effect just like whatsapp where the revealed view will be inflated over the top of other views. In my case when I apply the animation on a layout already present in the layout.xml of current java class then its work fine but the problem is that the revealing layout which in my case is LInearLayout will push the other contents(which are under it) down and make place for it.
My layout in this case is as follow,
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<io.codetail.widget.RevealFrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/reveal_items"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<ImageButton
android:layout_width="70dp"
android:layout_height="70dp"
android:background="#drawable/icon_camera" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Gallery" />
</LinearLayout>
<!-- Other 2 icons here-->
</LinearLayout>
</io.codetail.widget.RevealFrameLayout>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Enter Name" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="OK" />
LinearLayout/>
my reveal layout will push the EditText and button down to make place for it but i want to reveal over the top of them..
Then I tried to put the revealing view code in another reveal-layout.xml file and inflate that layout to a View(LinearLayout in my case) created in javacode. And then try to apply the revealing effect on this LinearLayout but it gives me this "cannot start this animator on a detached view" exception.
My revealing-layout.xml looks like
<io.codetail.widget.RevealFrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/reveal_items"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<ImageButton
android:layout_width="70dp"
android:layout_height="70dp"
android:background="#drawable/icon_camera" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Gallery" />
</LinearLayout>
<!-- Other 2 icons here-->
</LinearLayout>
</io.codetail.widget.RevealFrameLayout>
In button click i call function revealView();
which looks as below,
public void revealView()
{
int cx = (mRevealView.getLeft() + mRevealView.getRight());
int cy = mRevealView.getTop();
int radius = Math.max(mRevealView.getWidth(), mRevealView.getHeight());
// and all animations here, the animator is working fine so i did not put the code here
}
If i initialize mRevealView in my MainActivity onCreate() methoed as, mRevealView=(LinearLayout)findviewbyid(R.id.reveal_items) and inflate and assign view to it then the animator will work fine on this view. But when i try to create new layout like,
mRevealView=new LinearLayout(this) and set its parameters etc everything then it will gives this error when i apply animator on it.
Cannot start this animation on a detached view.
What I am doing wrong here can anybody suggest me.
Try to put your reveal code in a ViewTreeObserver of intended reveal-layout, something like this:
boolean reveal = false;
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
reveal = true;
}
});
LinearLayout layout = (LinearLayout) findViewById(R.id.reveal_items);
layout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if(reveal) {
reveal = false;
// start reveal animation here
// ...
}
// for SDK >= 16
ll.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
To achieve a similar effect like whatsapp using the Circular Effect like whatsapp library you mentioned i first set my parent view as FrameLayout. This parent Framelayout includes two childrens first is LinearLayout and second is FrameLayout(Here comes the code you want to display on top of view written in LinearLayout). Write all your code which you want display on the screen in the first LinearLayout and the reveal effect code in second FrameLayout as i mentioned. Its simply the use of FrameLayout property. You are good to go.
You can use the same java code provided in the discription of the library.
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
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
My main.xml layout simply contains two buttons and a content area, which shows below:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/myBtns"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<Button
android:id="#+id/btn_one"
android:layout_width="100dip"
android:layout_height="30dip"
android:text="button one"
/>
<Button
android:id="#+id/btn_two"
android:layout_width="100dip"
android:layout_height="30dip"
android:text="button two"
/>
</LinearLayout>
<LinearLayout
android:id="#+id/content_area"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<!--different button press will embed different content here-->
</LinearLayout>
</LinearLayout>
I would like to create my own tab-like feature that each button press will update the content(the content_area) below the buttons. So I have prepared two other content layout:
content_one.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView.../>
<Button .../>
</LinearLayout>
content_two.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<Gallery.../>
<Button .../>
</LinearLayout>
With all my simple codes showed above, I would like to implement the feature that:
in main.xml:
when button_one is pressed, content_one.xml will be embeded to the content_area of main.xml;
when button_two is pressed, the content_area of main.xml will be updated to content_two.xml
Which means using button to create a tab-like feature.
I tried:
button_one.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v){
LayoutInflater inflater = (LayoutInflater)MyActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View inflatedView = inflater.inflate(R.layout.content_one, null);
LinearLayout contentArea= (LinearLayout) findViewById(R.id.content_area);
contentArea.addView(inflatedView);
}
});
button_two.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v){
LayoutInflater inflater = (LayoutInflater)MyActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View inflatedView = inflater.inflate(R.layout.content_two, null);
LinearLayout contentArea= (LinearLayout) findViewById(R.id.content_area);
contentArea.addView(inflatedView);
}
});
The above code is partly working, what I mean is that when button_one is pressed, the content_area shows content_one.xml , or when button_two is pressed, the content_area shows content_two.xml , they are working fine!
But if either button is pressed firstly, then press the other one, the content remains in the old button triggered content. For example, when application first loaded, if firstly press button_one, content_one.xml is showing, after that , if I press button_two, the content is remain in content_one.xml.
My Question is how to remove the old content and show the new content when using LayoutInflater?
The problem is you're not removing the old view when adding the new one. Stick this line of code before you add the new view:
contentArea.removeAllViews()
Edit: Note that inflating the view every time the button is pressed, your previous state will always be lost. If you need to keep the state of the view I would go with Idistic's suggestion.
What others have done is simply hide one layout and then show the other
Stackoverlow how to change layouts dynamically
It's not exactly what you are asking but accomplishes the same thing
I have full screen RelativeLayout that contains the following:
1. FrameLayout, full screen, displaying content.
2. LinearLayout, act as a control menu, stay on top of the content #1, must be able to slide or fade in/out on request(I actually have two of these. One at the top of the screen, another at the bottom).
I have the view display correctly, the menu controller slide/fade in and out when menu button pressed. But when I slide and fade the view out, the click action remain. How do I remove this action?
I tried to call menuLayout.setVisibility(View.GONE); but the action remains.
I read some issue with TranslateAnimation but I cannot get it to work.
Can someone tell me how do I fix this? Example would be appreciated.
XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#99000000"
android:layout_alignParentLeft="true"
android:gravity="center_vertical"
android:id="#+id/contentFrame"
>
<ViewSwitcher
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/viewSwitch">
<include layout="#layout/main_car" />
</ViewSwitcher>
</FrameLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="43dp"
android:background="#drawable/um_top_bar"
android:layout_alignParentTop="true"
android:id="#+id/topMenu"
android:gravity="top"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/um_btn_home"
android:id="#+id/homeMainBtn" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/exp_menu_btn"
android:id="#+id/menuMainBtn" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FF000000"
android:layout_alignParentBottom="true"
android:id="#+id/bottomMenu"
android:gravity="top"
>
<include layout="#layout/menu_bottom" />
</LinearLayout>
Ok, I got it to work at last. For anyone who may face the same problem, here's what I did.
I place empty layer and separate all menu content into separate XML file.
Here's the code:
/** Resetting bottom menu content */
private void resetBottomMenu(boolean isOpen){
bottomMenu.removeAllViews();
bottomMenu.addView(loadBottomMenu(isOpen));
// Control event handler goes here.
}
/** Load bottom menu content from XML */
private LinearLayout loadBottomMenu(boolean isOpen){
LinearLayout result = null;
if(isOpen){
result = (LinearLayout)View.inflate(this.getApplicationContext(), R.layout.menu_bottom_open, null);
}else{
result = (LinearLayout)View.inflate(this.getApplicationContext(), R.layout.menu_bottom, null);
}
return result;
}
Every time I want to slide menu in, I called resetBottomMenu then start animation on bottomMenu. If I want to close the menu, I start animation then resetBottomMenu.
It's important to remove child view in that Layout since that will remove the click action.
P.S. I'm not sure if this is the best way of doing it but I can confirm that it works. I have three menu that need to be fade/slide and they work perfectly now :)