Android. Add controls programmatically - java

I have layout with controls:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/contact_phones_layout_row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="#+id/contact_phone"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:inputType="phone" />
<Spinner
android:id="#+id/contact_phone_type"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
And I want to inflate it into another layout on the fragment. Quantity of these controls depends on values in a array. Array contains controls objects. So every time onCreateView rises I filled the layout from the array:
private void addLine(PhoneLine line) {
LinearLayout layout = (LinearLayout) mLayout.findViewById(R.id.contact_phones_layout);
View view = line.getParent();
((ViewGroup) view.getParent()).removeView(view);
layout.addView(view, layout.getChildCount() - 1);
setButtonVisible(false);
}
if line is null controls are created this way:
private void addLine() {
LinearLayout layout = (LinearLayout) mLayout.findViewById(R.id.contact_phones_layout);
View view = inflater.inflate(R.layout.contact_phone_line, layout, false);
EditText phoneEditText = (EditText) view.findViewById(R.id.contact_phone);
Spinner phoneType = (Spinner) view.findViewById(R.id.contact_phone_type);
phoneLines.add(new PhoneLine(phoneEditText, phoneType, view));
layout.addView(view, layout.getChildCount() - 1);
}
But after that I get same values in all EditText/Spinner controls, values equal to last element in the array. What can be wrong? May be there is more pure way to add controls dynamically?

I fixed it by adding controls when onResume rises, not onCreateView. But I still don't understand why onCreateView changes all values.

Related

Custom Android Spinner Layout Issue

I am customizing an android Spinner Widget. I am trying to use different background colors against the list items. This is working, but when there are more items in the spinner control, the list items are not occupying the full space horizontally, thus showing white space on the popup view.
For small number of items, it is working fine.
I have tried custom and default Layout customizations.
JAVA Custom Spinner View Code
#Override
public View getView(int pos, View view, ViewGroup parent)
{
LayoutInflater objInflater = LayoutInflater.from(context);
view = objInflater.inflate(R.layout.spinner_item_colored, null);
LinearLayout llOption = (LinearLayout) view.findViewById(R.id.llOption);
TextView tvOption = (TextView) view.findViewById(R.id.tvOption);
if (alDefects.get(pos).sNature.equalsIgnoreCase("1"))
llOption.setBackgroundColor(getResources().getColor(R.color.majorDefect));
else if (alDefects.get(pos).sNature.equalsIgnoreCase("2"))
llOption.setBackgroundColor(getResources().getColor(R.color.criticalDefect));
else
llOption.setBackgroundColor(getResources().getColor(R.color.minorDefect));
tvOption.setTextColor(getResources().getColor(R.color.white));
tvOption.setText(alDefects.get(pos).sDefect);
return view;
}
XML Code:
<LinearLayout
android:id="#+id/llOption"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_weight="1"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:layout_margin="0dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="#+id/tvOption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical|left"
android:singleLine="false"
android:textColor="#444444"
android:textSize="13dp" />
I want the spinner popup to use full available width for Background color when there is a scrollbar.
Please click this Link to see the Sample Output
When you use weight you should set android:layout_width="0dp"

Getting Child from linear layout

I created layout file, consist of one linearlayout and two nested linearlayout inside the main one. When I using getParent method, it select the second nested linearlayout. My target was the first one nested linearlayout. So I gives the first nested linearlayout a ID called linear_top. Then I declared in the onCreateView, test and debug, I have no luck it shows that is null.
My target was AnimatedGifImageView
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/linear_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/music_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Love Story"
android:textAppearance="?android:attr/textAppearanceLarge" />
<com.music.flow.lib.AnimatedGifImageView
android:id="#+id/music_anim"
android:layout_width="match_parent"
android:layout_height="76dp"
android:scaleType="fitXY"
android:contentDescription="Animation"
/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<RatingBar
android:id="#+id/music_rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="40dp"
android:numStars="4"
android:rating="3.5" />
<ImageView
android:id="#+id/btn_playmusic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:src="#drawable/resume" />
</LinearLayout>
OnCreateView
linearTop = (LinearLayout) v.findViewById(R.id.linear_top);
AnimatedGifImageView animatedGifImageView =
(AnimatedGifImageView) linearTop.getChildAt(1); /* Null Exception */
Child views are indexed from 0. In other words, the first child view is 0, the second child view is 1... and so on.
Also, why don't you just get the the ImageView by it's ID?
AnimatedGifImageView musicAnim = (AnimatedGifImageView) findViewById(R.id.music_anim);
#Override
public View onCreateView(View v, String name, Context context,
AttributeSet attrs) {
LinearLayout linearTop = (LinearLayout) v.findViewById(R.id.linear_top);
ImageView animatedGifImageView = (ImageView) linearTop.getChildAt(1); // NullPointer
return super.onCreateView(v, name, context, attrs);
}
Does your code look like this? You are getting a NullPointerException because in onCreateView, the parameter View v may be null, as mentioned in the docs here. Are you using fragments? If not, then don't use onCreateView. Place your code instead in onCreate like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout linearTop = (LinearLayout) findViewById(R.id.linear_top);
ImageView animatedGifImageView = (ImageView) linearTop.getChildAt(1);
setContentView(R.layout.activity_nested_linearlayout);
}
also, as what Sound Conception mentioned, you could just try to get the view directly by using its id instead of manually getting it using an index.

Setting the number of viewable item count in listView

Is there a way to set the viewable item count for a listview? or am I obliged to set the height for the listview?
For instance, I got a list that includes 9 items. I only want 4 of them to appear at first. Then user needs to scroll to see other items.
list_anlam.xml
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="1dp"
android:background="#android:color/darker_gray" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/title_popup_hikayeoku" />
<EditText android:id="#+id/kelime_text"
android:inputType="text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<ListView android:id="#+id/list_anlam"
android:layout_width="match_parent"
android:layout_height="wrap_content"></ListView>
<Button
android:id="#+id/button_sec"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/button_popup_hikayeoku" />
</LinearLayout>
list_item.xml :
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20sp"
android:padding="10dp" />
Where I fill items into listview : HikayeOkuActivity.java is
String[] anlamlar = null;
anlamlar = MainActivity.dbM.ilkAnlamGetir(selectedText);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.list_item,anlamlar);
anlamList.setAdapter(adapter);
popupWindow.showAsDropDown(mainLayout, touchedX,touchedY);
Yes, you need to get the height of the listview. In your onCreate you do something like:
listview.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
height = listView.getHeight();
}
In the getView method of your adapter you then use the height divided by four to set the height of each list item.
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = activity.getLayoutInflater();
View rowView = inflater.inflate(R.layout.item_layout, parent, false);
rowView.setMinHeight(height/4);
return rowView;
}
Now this should preferably be done with a ViewHolder, but that's not the topic here.
Basically, the height of each view must be 1/4 of the height of your ListView. If you want to support all device resolutions, you have to calculate it. If you need more info about that, add a comment and I will explain it in detail.
Important for details, what kind of Adapter are you using for your ListView?
Correct me if I'm wrong, but..
you could also use an android:WEIGHTSUM and android:WEIGHT parameters in your xml layouts. Set android:weightsum=1 for parent view (your ListView) and android:weigth=0.25 for child views (layout of ListView items). In this case you don't have to calculate heights of your viewables.

Android - How to set the right on click event to a button that was made programmatically

I've made the next layout xml code which I call it layout_one -
<?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:orientation="vertical" >
<LinearLayout
android:id="#+id/layout_one"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="50dp"
android:layout_marginTop="50dp"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="100dp"
android:text="Testing 1"
android:textSize="20sp" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/info_layout"
android:visibility="gone">
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
As you can see there are two layout in it - one with textview and button and one with textview.
The layout with the only textview - is gone, And i want by a click on the button, from the visible layout, it will be shown.
Now at the activity i wrote the next code -
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_layout);
ScrollView sv = new ScrollView(this);
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
sv.addView(ll);
LinearLayout newView0 = (LinearLayout)View.inflate(this, R.layout.layout_one, null);
LinearLayout newView1 = (LinearLayout)View.inflate(this, R.layout.layout_one, null);
LinearLayout newView2 = (LinearLayout)View.inflate(this, R.layout.layout_one, null);
LinearLayout newView3 = (LinearLayout)View.inflate(this, R.layout.layout_one, null);
ll.addView(newView0);
ll.addView(newView1);
ll.addView(newView2);
ll.addView(newView3);
setContentView(sv);
newView1.findViewById(R.id.layout_one).setBackgroundColor(0xff0000ff);
TextView tv3 = (TextView) newView3.findViewById(R.id.textView1);
tv3.setText("Suprise Suprise");
infoLay = (View) findViewById(R.id.info_layout);
ll.addView(newView3);
}
Now there is something I don't understad - How could I set an on click listener to the button that will know which layout to show?
Tanks for any kind of help
Actually, there are three linear layouts, which seems redundant.
You can set the onclick listener by checking if textview of each layout is empty or not.
First off, have a look at this http://developer.android.com/training/improving-layouts/reusing-layouts.html. Use that <include> tag instead of dynamically creating all these layouts in your Activity class. Define your ScrollView, and all your LinearLayouts in your test_layout.xml file.
Then, in your Activity, all you have to do is get a reference to those views that's you've defined using findViewById.
Once you've got that working we can address your question as follows:
setContentView(R.layout.test_layout);
LinearLayout layout1 = (LinearLayout)findViewById(R.id.layout1);
LinearLayout layout2 = (LinearLayout)findViewById(R.id.layout2);
LinearLayout layout3 = (LinearLayout)findViewById(R.id.layout3);
OnClickListener listener = new OnClickListener() {
#Override
public void onClick(View view) {
((View)view.getParent().getParent()).findViewById(R.id.textView2).setVisibility(View.VISIBLE);
}
});
layout1.findViewById(R.id.button1).setOnClickListener(listener);
layout2.findViewById(R.id.button1).setOnClickListener(listener);
layout3.findViewById(R.id.button1).setOnClickListener(listener);
I'd also add that it seems like you're trying to create a list here, in which case you should use a ListView instead of many LinearLayouts.

Crash when setting parameter to layout in Android

Expected Result
Clicking on the toggle button will show up the menu and slide out the content view rightward. After animation is finished, the layout parameters of the content view gets updated to the final position.
Problem
When updating the final position of the content view, the statement mViewContent.setLayoutParams(params); causes the crash. The error message is java.lang.ClassCastException: android.widget.LinearLayout$LayoutParams
Source Code
Main.java > public class MainActivity extends Activity {}
public void onToggleButtonMenuClicked(View view) {
// Is the toggle on?
boolean toggleTurnedOn = ((ToggleButton) view).isChecked();
if (toggleTurnedOn) { // If the toggle is turned on
// Show menu
LinearLayout mViewMenu = (LinearLayout) findViewById(R.id.linear_layout_menu);
Animation animMenuOn = AnimationUtils.loadAnimation(MainActivity.this, R.anim.anim_menu_on);
mViewMenu.startAnimation(animMenuOn);
LinearLayout mViewContent = (LinearLayout) findViewById(R.id.linear_layout_content);
Animation animContentOff = AnimationUtils.loadAnimation(MainActivity.this, R.anim.anim_content_off);
mViewContent.startAnimation(animContentOff);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(480, 800);
params.leftMargin = 384; // Shift 384 pixels from left screen border
params.rightMargin = -96; // Exceed 96 pixels from right screen border
mViewContent.setLayoutParams(params); // This statement causes crash!
} else {
// Hide menu...
} // End of toggle events handling
} // End of onToggleButtonMenuClicked()
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="329dp"
android:layout_height="wrap_content" >
<!-- The Menu View -->
<LinearLayout
android:id="#+id/linear_layout_menu"
android:layout_width="263dp"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/table_row_1_search_bar"
android:layout_width="match_parent"
android:layout_height="40dp"
android:weightSum="10"
android:orientation="horizontal" >
<EditText
android:id="#+id/edit_text_search_id"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="7"
android:hint="#string/edit_text_search_id"
android:textSize="14sp" />
<Button
android:id="#+id/button_search_id"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="3"
android:text="#string/button_search_id" />
</LinearLayout>
<!-- Other rows in the menu are omitted -->
</LinearLayout> <!-- End of Menu -->
<!-- The Content View -->
<LinearLayout
android:id="#+id/linear_layout_content"
android:layout_width="329dp"
android:layout_height="match_parent"
android:orientation="vertical" >
<ToggleButton
android:id="#+id/toggle_button_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onToggleButtonMenuClicked" />
<TextView
android:id="#+id/text_content"
android:layout_width="480dp"
android:layout_height="wrap_content"
android:text="#string/text_content" />
</LinearLayout> <!-- End of Content -->
</FrameLayout> <!-- End of the root linear layout -->
mViewContent params should be added with resp to your Parent view, suppose you have parent view as LinearLayout then, LinearLayout.LayoutParams must be used.
Explanation (Adapted from here):-
Take for example, LinearLayout.LayoutParams and RelativeLayout.LayoutParams, they are different independent classes. They store different additional information about child views... say..
LinearLayout.LayoutParams can associate weight value with each
view, while RelativeLayout.LayoutParams can't.
RelativeLayout.LayoutParams can have values like alightWithParent,above, below
with each view while LinearLayout.LayoutParams can't.
Although the code will not give compile time error because all LayoutParams have same parent class i.e. ViewGroup.LayoutParams. So, it is always essential, to assign Layout params with respect to parent layout..
make sure you imported the correct layout params
import android.widget.LinearLayout.LayoutParams;

Categories

Resources