Dynamically choose a view in android app - android

I have an android app, and i want it to have two views which are similar to one another.
For example :
<Button
android:id="#+id/ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="OK" />
and
<Button
android:id="#+id/ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OK" />
notice that the only change is that i removed the centerHorizontal line. but this is a simplified example.
Now, i want to create an app, that sometimes (ex- using a random func) uses view A and sometimes uses view B.
Is it possible to do this "views switch" at runtime?
Is it possible to build this app using the two views (notice that the button should have the same ID, i don't want to implement the logic twice)?
thanks a lot!

The only way I imagine to do that is:
Having each button in its own layout file.
Inflate the corresponding based on your function result.
Append it to the view.
Sample code:
button_a.xml:
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="OK" />
button_b.xml:
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OK_2" />
Your activity:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LayoutInflater inflater = LayoutInflater.from(this);
Button button;
if (Math.random() > 0.5) {
button = (Button) inflater.inflate(R.layout.button_a, null);
} else {
button = (Button) inflater.inflate(R.layout.button_b, null);
}
/* ...
Set listeners to the button and other stuff
...
*/
//find the view to wich you want to append the button
LinearLayout view = (LinearLayout) this.findViewById(R.id.linearLayout1);
//append the button
view.addView(button);
}
If you want this to happen dynamically (i.e. not in the onCreate, but after some user input) you can always remove the button from layout, and inflate a new random-chosen one.
Hope this helps!

Related

Leanback focus problems

Hello guys I'm working on application and my layout structure is as following :
RelativeLayout:
CompoundView:
CompoundView:
RelativeLayout:
Button
Button
RecyclerView
BrowseFragment:
Only rows
My problem is when I get to first row of browse fragment and first item in it and I want to go up (D-PAD-UP) to focus button it does nothing it works only when I push left ( D-PAD-LEFT). Anyone has solution for this ?
So the problem was in BrowseFrameLayout for some reason and to solve this issue I had to override onFocusSearchListener and manage focus myself.
In BrowseFragment which I extended I have this method :
public void workaroundFocus(){
if(getView() != null) {
View viewToFocus = getActivity().findViewById(R.id.view_to_focus);
BrowseFrameLayout browseFrameLayout = getView().findViewById(android.support.v17.leanback.R.id.browse_frame);
browseFrameLayout.setOnFocusSearchListener((focused, direction) -> {
if (direction == View.FOCUS_UP) {
return viewToFocus;
}
else {
return null;
}
});
}
}
And then:
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
workaroundFocus();
/*
Rest of the code
*/
}
And voila it works.
Since you are using the RelativeLayout you should layout the components in the order that you would like to be navigated.
Using the XML attributes presented in the RelativeLayout reference document, you will be able to establish an navigation order too:
<?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"
android:paddingLeft="16dp"
android:paddingRight="16dp" >
<EditText
android:id="#+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/reminder" />
<Spinner
android:id="#+id/dates"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_below="#id/name"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#+id/times" />
<Spinner
android:id="#id/times"
android:layout_width="96dp"
android:layout_height="wrap_content"
android:layout_below="#id/name"
android:layout_alignParentRight="true" />
<Button
android:layout_width="96dp"
android:layout_height="wrap_content"
android:layout_below="#id/times"
android:layout_alignParentRight="true"
android:text="#string/done" />
</RelativeLayout>
Here the dates Spinner is below the name EditText and at left of times Spinner, the times component is below the name one and the done Button is below times. See the image below:
See the Build Basic TV Layouts guide for more tv related details.

Is defining a ButtonView as a View or as a Button same?

While I was reading a tutorial for how to create layouts dynamically, I found that the buttons in the xml file are defined as a view as shown below, and not as I expected to be defined as buttons. Are either ways of defining a view element the same or there are differences?
xml:
<LinearLayout
android:id="#+id/linearLayout00"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="horizontal">
<Button android:text="Add View"
android:id="#+id/addBtn00"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".5" />
<Button
android:text="Remove View"
android:layout_height="wrap_content"
android:id="#+id/removeBtn00"
android:layout_width="0dp"
android:layout_weight=".5" />
</LinearLayout>
Java_Code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
View buttonAdd = findViewById(R.id.add);
buttonAdd.setOnClickListener(this);
View buttonRemove = findViewById(R.id.remove);
buttonRemove.setOnClickListener(this);
The Button class is a subclass of View. Polymorphism allows us to use subclasses in place of the parent class, however, you will only be able to access the methods from the View class, not any methods specific to the Button class.
This means you will not be able to call methods like setText() (which the Button class inherits from TextView, which in turn inherits from View)
If you want to cast it to a button you should write:
Button buttonAdd = (Button) findViewById(R.id.add);

How to change weight of a button programatically

I have a CountDownTimer that is activated by a "Set" button and then can be stopped by a "Cancel" button.
When the activity starts, I want only the set button to show. When the countdown is started, I want to hide the "Set" button and show the "Cancel" button.
I want to do this by changing the weight of the button. How do I do this? I have found similar questions that have answers that don't work when I try them. I think those answers are just fragments of the full code, which is what I'm looking for.
Here is the XML:
<LinearLayout
android:id="#+id/buttonsContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" >
<Button
android:id="#+id/setDelay"
android:layout_width="0dip"
android:layout_height="fill_parent"
android:layout_weight="1"
android:onClick="activateDelay"
android:text="Set Delay" />
<Button
android:id="#+id/cancelDelay"
android:layout_width="0dip"
android:layout_height="fill_parent"
android:layout_weight="1"
android:onClick="cancelDelay"
android:text="Cancel Delay" />
</LinearLayout>
I know I'm using hard-coded strings, they're just for development purposes.
Why do you want to use the weight property to hide a button? layout_weight is used to share space proportionately (according to the weights given). I guess you could "hide" a button by setting the layout_weight to 0 (and the weight on the other to something greater than 0). I've never updated the layout parameters after adding the views to viewgroup, but parent.updateViewLayout(childView, updatedParams) looks promising.
In any case, use setVisibility(View.GONE) on the button you want gone; it is hidden and the rest of the Views are laid out as though the button is not present. (You can use View.INVISIBLE to hide the View, but the rest of the Views are laid out as though the button is there - you just can't see it.)
Here's an untested "fragment" ;P
private Button set;
private Button cancel;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// it's typical to use underscore notation for IDs - R.id.set_delay
set = (Button) findViewById(R.id.setDelay);
cancel = (Button) findViewById(R.id.cancelDelay);
}
public void activateDelay(View button) {
set.setVisibility(View.GONE);
cancel.setVisibility(View.VISIBLE);
}
public void cancelDelay(View button) {
set.setVisibility(View.VISIBLE);
cancel.setVisibility(View.GONE);
}
And in your XML, you'd start with the "Set" button visible (by default), and "Cancel" gone, both with match_parent for width:
<LinearLayout
android:id="#+id/buttonsContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true">
<Button
android:id="#+id/setDelay"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:onClick="activateDelay"
android:text="Set Delay" />
<Button
android:id="#+id/cancelDelay"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:visibility="gone"
android:onClick="cancelDelay"
android:text="Cancel Delay" />
</LinearLayout>

How to add another layout number of time to my already created LinerLayout?

Here is my Prent layout (main.xml)
<!-- ============================================================ -->
<!-- All Employees are added here (added and More then one) -->
<!-- ============================================================ -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/myLayout"
android:orientation="vertical"
android:layout_gravity="center_vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#00000000">
<!-- ++++++++ here extra layout is added programmatically -->
</LinearLayout>
Here is my another layout file that I want as child, say child.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearLayout2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:gravity="center_vertical"
android:orientation="horizontal" >
<Button
android:id="#+id/btn_left"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:singleLine="false"
android:maxLines="2"
android:text="hello"/>
<TextView
android:id="#+id/list_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:gravity="center_horizontal"
android:text="Photos"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Button
android:id="#+id/btn_right"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="Save" />
</LinearLayout>
Now in my Main activity I am calling the main.xml and based on the for loop condition I want to add the layout of the child.xml and every time I want to set the different value of the TextView of child.xml
So how it is Possible?
I have done like this:
private void doCalculationForMultipleEmployee() {
singleEmployee.setVisibility(View.GONE);
for (int i = 0; i<=tempEmployerList.size()-1; i++) {
View repeatedLayout = LayoutInflater.from(getApplicationContext()).inflate(R.layout.test);
((TextView)repeatedLayout.findViewById(R.id.list_title)).setText("Employee"+i);
// customize repeatedLayout with other data
myLinearLayout.addChild(repeatedLayout);
}
}
But after doing that I got syntax error at .inflate and at .addChild
So where have I gone wrong? Please help me by some code to add it by for loop.
Just create a loop like below:
LinearLayout parent=findViewById(R.id.myLayout);
for(int i=0;i<list.size();i++)
{
LinearLayout llItem=(LinearLayout)LayoutInflater.createFromSource(R.layout.child, null);
TextView txt= (TextView)llItem.findViewById(R.id.title);
txt.setText(list.get(i));
parent.add(llItem);
}
Inflate the view then add to the parent
LinearLayout parent = (LinearLayout)findViewById(R.id.myLayout);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
Layout child = inflater.inflate(R.layout.myLayout2, null);
TextView title = (TextView)child.findViewById(R.id.list_title);
parent.addView(child);
Repeat as many times as necessary or use a loop
If i understood your question correctly you need to display button, textview and button side by side in your layout.
If you want this you just take listview and use custom adapter, with this you can display button, text and button side by side

Add ExpandableListView to a tab with other elements

I am developing an app with tabs. On one of the tabs,
I have two EditText fields and a couple of buttons. I want to add an ExpandableListView
to the tab, below the rest of the elements.
My problem is that the current class extends Activity. All the example I've found extend ExpandableListActivity, but I can't extend both for the same class.
How can I add this list to the tab? I've added an ExpandableListView element in the XML file, but whenever I run it, it doesn't show up. I understand that I need to bind the view to some data, but how do I go about doing this?
Thank you.
Here is my class code:
public class DirectionsTab extends Activity
{
private Button clear_btn;
private Button go_btn;
private EditText origin_txt;
private EditText dest_txt;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.directions_tab);
// initialize views and onClick event handler
origin_txt = (EditText)findViewById(R.id.origin_txt);
dest_txt = (EditText)findViewById(R.id.dest_txt);
clear_btn = (Button)findViewById(R.id.clear_btn);
// clear all text fields and return focus to dest_txt
clear_btn.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v)
{
origin_txt.setText("");
dest_txt.setText("");
origin_txt.requestFocus();
}
});
} // end public void onCreate(Bundle savedInstanceState)
} // end public class DirectionsTab extends Activity
and 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="fill_parent">
<TextView
android:id="#+id/origin_lbl"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Origin"/>
<EditText
android:id="#+id/origin_txt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#android:drawable/editbox_background"
android:layout_below="#id/origin_lbl"/>
<TextView
android:id="#+id/dest_lbl"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/origin_txt"
android:text="Destination" />
<EditText
android:id="#+id/dest_txt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#android:drawable/editbox_background"
android:layout_below="#id/dest_lbl" />
<ExpandableListView
android:id="#+id/listView"
android:layout_below="#+id/dest_txt"
android:layout_height="wrap_content"
android:layout_width="wrap_content" /><!--android:id="#android:id/list"-->
<Button style="?android:attr/buttonStyleSmall"
android:id="#+id/clear_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/dest_txt"
android:layout_alignParentRight="true"
android:layout_marginLeft="10dip"
android:layout_marginTop="10dip"
android:text="Clear" />
<Button style="?android:attr/buttonStyleSmall"
android:id="#+id/go_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="#id/clear_btn"
android:layout_alignTop="#id/clear_btn"
android:text="Go!" />
</RelativeLayout>
I got this!, If anyone is having problems with this, make sure you follow these steps:
Copy and paste ExpandableList3 example (located in ApiDemos project from Samples folder in your Android SDK). This is just a good example of how to set up a list.
Make your class inherit from ExpandableListActivity
Create the following in your XML layout file:
<ExpandableListView
android:id="#android:id/list"
android:layout_below="#+id/go_btn"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"/>
It is VERY important that the ID property matches what you see above, otherwise, nothing will work. This little detail wasted plenty of hours for me and was discovered seating neatly as a small detail in the android docs.

Categories

Resources