I have a problem button visibility. I have 2 button from titlebar.One of them edit, one of them done. First I want to see just edit button and when i clicked edit button, edit button visibility will be false and done button visibility true.
I get their id from xml and when i click one of them i want to change visibility but edit.setVisibility(); it doesnt work.What is wrong?I can see edit button.I want to change buton visibility programmatically.
Can anybody have any idea?
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final boolean customTitle = requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.main);
edit=(Button)findViewById(R.id.edit);
done=(Button)findViewById(R.id.done);
edit.setVisibility(View.INVISIBLE);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,R.layout.main);
if ( customTitle ) {
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,R.layout.main);
}
main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button android:id="#+id/edit"
android:layout_width="57px"
android:layout_height="wrap_content"
android:text="edit"/>
<Button android:id="#+id/done"
android:layout_width="57px"
android:layout_height="wrap_content"
android:text="done"/>
</LinearLayout>
First, you're missing the android:orientation parameter in your LinearLayout.
Second, if you want to change between edit and done you can do this:
edit.setVisibility(View.GONE);
done.setVisibiluty(View.VISIBLE);
and the opposite to change to edit button again.. With View.INVISIBLE the button will not show but still use the space where it was.
The problem is that setFeatureInt just sets the resource ID for the title, which will cause a new inflation of the layout resource, which will be placed in a system FrameLayout called id/title_container. This can be inspected using the Hierarchy Viewer in eclipse.
Essentially, you end up with two instances of the main layout. One set as the content view (below the title) and the other set as the title. When you call findViewById, it will only look in the content view for any views matching the ID. This means that the edit and done buttons you retrieve are the ones in the content view.
If you want to access the buttons in the title area, you can use
View v = getWindow().getDecorView();
edit=(Button)v.findViewById(R.id.edit);
done=(Button)v.findViewById(R.id.done);
edit.setVisibility(View.INVISIBLE);
This will search through the whole view structure of the window, not just the content view, thus solving your problem.
Related
I have a LinearLayout that contains a TextView, and always will. There will also always be at least one button located below the TextView, but there might be more than one under certain circumstances.
I can successfully create and add as many buttons as I need programmatically. I can also successfully set whatever appearance related parameters/options that I require for these buttons programmatically.
The problem is that I don't know how to tell a programmatically created button that it should use a XML resource file, which contains the appearance and layout parameters, instead of setting these parameters programmatically.
I've looked at similarly named questions and spent time messing with the API itself, to no avail.
Edit:
Here's an approximation of what I'm trying to do that will hopefully make explanations a bit clearer for me:
private TextView textView;
private SomeObject someObject;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View scrollView = inflater.inflate(R.layout.fragment_play_game, container, false);
textView = (TextView) scrollView.findViewById(R.id.game_data_text);
textView.setText(someObject.getTextForTextView());
LinearLayout layout = (LinearLayout) scrollView.findViewById(R.id.game_data_container);
for (String optionText : someObject.getTextForButtons()) {
layout.addView(createOptionButton(optionText, layout));
}
return scrollView;
}
private View createOptionButton(String optionText, LinearLayout layout) {
Button optionButton = new Button(this.getActivity());
// set button layout/options here, somehow??
optionButton.setText(optionText);
return optionButton;
}
My XML layout file for the fragment looks like this (It's this LinearLayout that I'm trying to add buttons to):
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/game_data_container"
etc... >
<TextView
android:id="#+id/game_data_text"
etc... />
</LinearLayout>
</ScrollView>
Also, if I'm to create an XML layout file for the button (lets call it custom_button.xml) should it look something like this?:
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/play_game_option_button"
etc... />
Update:
Just to expand a bit on what MrFox# is talking about, what I did to get it working was replace this line:
Button optionButton = new Button(this.getActivity());
with this one:
Button optionButton = (Button) inflater.inflate(R.layout.play_game_option_button, layout, false);
...which inflates an xml file containing only a Button layout (the button template). In this case, it returns the root view of that file, which is just the button because there's no parent above the button in the file.
However, if I had have set the last boolean value (attachToParent) to true, it would have returned the root container that the button will be in (which is just the 'layout' variable that was passed into the call).
I can now produce as many buttons as I want using this template.
Have you thought of making a layout that is just the button with the applied XML styles and then inflating it into your linear layout?
something like:
inflater.inflate(R.layout.StyledButton, MyLinearLayout, true);
xml for your button under /res/layout/my_button_layout.xml
<Button xmlns:android="http://schemas.android.com/apk/res/android"
... />
code in your activity
myButton = (Button)inflate.inflate(R.layout.my_button_layout, null);
myView.addView(myButton);
want to make an Android app that starts with a main layout and when you push a button (called stateButton) that is in this layout the layout changes to a main2 layout containing another button (called boton2), and when you push this one you get back to the first main.
I want to do this in the same activity without creating or starting another one.
Here I show you part of the code:
public class NuevoshActivity extends Activity
implements SensorEventListener, OnClickListener {
private Button stateButton;
private Button boton2;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.stateButton = (Button) this.findViewById(R.id.boton);
this.boton2 = (Button) this.findViewById(R.id.boton2);
stateButton.setOnClickListener(this);
boton2.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if(v==stateButton) {
setContentView(R.layout.main2);
}
else if(v==boton2) {
setContentView(R.layout.main);
}
}
}
The mains only have some images, text views and the buttons.
But I've some troubles. Can't it just be as simple as that or what am I missing or what is wrong?
When you use findViewById, you are actually trying to find a view inside the layout you specified by the setContentView. So using setContentView again and again might bring problems when you are trying to check for buttons.
Instead of using a setContentView, I would add the 2 layouts for the screen as child's for a view-flipper which only shows one child at a time. And you can specify the index of which child to show. The benefit of using a view flipper is that you can easily specify a 'in' and 'out' animation for the view if you need an animation when you switch between views. This is a lot cleaner method then recalling setContentView again and again.
The FrameLayout handles this wonderfully... Use this with the <include... contstruct to load multiple other layouts, then you can switch back and forth between them by using setvisibility(View.VISIBLE); and setVisibility(View.INVISIBLE); on the individual layouts.
For example:
Main XML including two other layouts:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout android:id="#+id/frameLayout1" android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android">
<include android:id="#+id/buildinvoice_step1_layout" layout="#layout/buildinvoice_step1" android:layout_width="fill_parent" android:layout_height="fill_parent"></include>
<include android:id="#+id/buildinvoice_step2_layout" android:layout_width="fill_parent" layout="#layout/buildinvoice_step2" android:layout_height="fill_parent"></include>
</FrameLayout>
Code to switch between layouts:
findViewById(R.id.buildinvoice_step1_layout).setVisibility(View.VISIBLE);
findViewById(R.id.buildinvoice_step2_layout).setVisibility(View.INVISIBLE);
You will also need to set the visibility of the individual layouts when the activity starts (or in XML) otherwise you will see them both - one on top of the other.
Your boton2 button will be NULL because the definition of the button is in main2.xml.
The only views you will be able to find are the views which are defined in main.xml.
Thanks!!! All the info was usefull to understand a lot of things and as C0deAttack commented I've got troubles with the button on the main2. What I've done is to set View.VISIBLE and View.GONE to the TextViews and Buttons that I wanted in each layout. Thank you very much.
I want to create the instruction, so when user press the next button I want to set to the
next layout page. I tried setContentView(R.layout.aboutus); but it looks like to set the new
layout to particular page.
Layout:
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:background="#dddddd">
<LinearLayout android:gravity="center" android:background = "#drawable/aboutus"
android:orientation="vertical" android:layout_height="wrap_content"
android:layout_width="wrap_content"/>
</LinearLayout>
code :
public void onItemClick(AdapterView<?> parent, View view, int position,
long lg) {
switch (position) {
case 4:
setContentView(R.layout.aboutus);
}
}
So, I want to know how to go to next layout without new activity and can be back to previous page. Thank you.
You should use a ViewFlipper.
Get a reference to the ViewFlipper:
ViewFlipper myViewFlipper = (ViewFlipper) findViewById(R.id.my_viewFlipper);
You then inflate each page as a view:
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.your_layout_id, null);
And then add it to the ViewFlipper:
myViewFlipper.addView( view );
Then when the user hits the button for next page you call this method:
myViewFlipper.showNext();
Or if you want the previous page:
myViewFlipper.showPrevious();
Use a ViewSwitcher or ViewFlipper.
You can try to place the same page in your layout and set all it's component to have Visibility.GONE set, and when you press the button, to set all your visible widgets to GONE and others to Visible. Or you can try a dynamically inflate procedure ( to inflate your views ) since you can use separate layout to inflate views.
Check this for more information about inflate
http://developer.android.com/reference/android/view/LayoutInflater.html
May be you could do this:
If you have two different layouts and one wanna each one at one time.
First get the id's of each layout by findviewbyid method.
then use
firstlayout.setVisibility(View.VISIBLE).
secondlayout.setVisibility(View.GONE);
for showing first layout.
When you press button, in its click listener make
firstlayout.setVisibility(View.GONE).
secondlayout.setVisibility(View.VISIBLE);
it works but the layouts should be seperate.
Hope it helps.
Hey guys please help me out I am new to android application development
Here is the scenerio: This is my layout declaring xml file:
<LinearLayout xxx
<Textview aaa>
</TextView>
</LinearLayout>
//The below LinearLayout I need to display when it meets some condition in java class
i.e if(true) then display the following layout else dont. I can check this condition only after user provides some input.
<LinearLayout xxx
<Textview aaa>
To be displayed after the condition is checked
</TextView>
</LinearLayout>
//following layout is displayed with the first one.
<LinearLayout xxx
<Textview aaa>
</TextView>
</LinearLayout>
Any idea how to do it?
Take a few moments to read the android dev guide. It is worth the time: http://developer.android.com/guide/topics/ui/index.html
Basically, you want to use IDs to refer to the xml layout:
android:id="#+id/myxmlid"
and in your java file:
LinearLayout ll = findViewById(R.id.myxmlid);
if (yourCondition)
mainLayout.add(ll);
I'm assuming that you want to add a widgets to the current layout, rather than just change the text of the current TextView.
Also, this assumes that you want to add more than just a new TextView. If you only need that, you don't need to wrap it in a LinearLayout, which is used to add rows or columns of widgets.
You don't replace your entire layout programmatically just to change the text in one TextView. The way this kind of thing is handled in android, is to include a field in your Activity class for your textview, then instantiate it in your onCreate() method with findViewById() after you've called setContentView() to load the layout so that you can access that TextView's fields and methods.
First, you TextView needs an id in the layout xml.
<TextView android:id="#+id/sometext"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Then in your Activity...
TextView mTextView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTextView = (TextView) findViewById(R.id.sometext);
}
Somewhere else in the program...
public void myMethod(){
mTextView.setText("Text says this now");
}
Hopefully that gets the idea across. Good luck!
Thank Aleadam for suggesting me to read the link. Follwoing was my approach to get the output.
What I did was I assigned my LinearLayout Visibility to "GONE" (android:Visibility="GONE") when declarning the XML, and in the program after the condition is met, changed the visibility to "VISIBLE". (by using layout.setVisibility(View.VISIBLE))
Please refer the image given in the url
http://docs.google.com/Doc?docid=0AQhgDtGvE2HgZGZ6cmtua185M2RneG5nYmNm&hl=en
My query is, How can I display the messages corresponding to the rounded buttons and the table row , when I click on the rounded button with question mark.
I know, I have to use listener for the ? button , but what should I do in listener exactly, such that when I click, it shows those alerts(images) and when I click again, it disappears.
For this UI, I have used Relative layout as was suggested here -- Aligning components at desired positions -- and it worked perfect for me.
So, do I need to change my base layout altogether for accomplishing this?
You can use a FrameLayout as the base for your ui layout and then add an ImageView overlay. For example:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/MainFrame"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- Put your normal layout stuff here -->
</FrameLayout>
Then in your code you can create the ImageView and add it to the MainFrame and it will overlay your UI, like this:
FrameLayout mainFrame = (FrameLayout)findViewById(R.id.MainFrame);
ImageView overlay = new ImageView(this);
overlay.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.overlay));
mainFrame.addView(overlay);
Then later you can call:
mainFrame.removeView(overlay);
to have it go away.