Dynamically adding a child to LinearLayout with getting each child's position
Solution 1
your problem is resources.... you use the setText(int) method (that index is int...) which looks for resources and not string, this is not StringBuilder for which you can throw any type and get a string. you needs to replace
tv.setText(ll.indexOfChild(v));
with
tv.setText(Integer.toString(ll.indexOfChild(v)));
and if you want even little bit of efficiency:
public class TestActivity extends Activity {
private String[] categories;
private LinearLayout ll;
private TextView tv;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
categories = getResources().getStringArray(R.array.categories);
tv = (TextView) findViewById(R.id.text);
ll = (LinearLayout) findViewById(R.id.hsvLinearLayout);
for(int i = 0; i < categories.length; i++) {
Button btn = new Button(this);
btn.setText(categories[i]);
btn.setOnClickListener(buttonClick);
ll.addView(btn);
int idx = ll.indexOfChild(btn);
btn.setTag(Integer.toString(idx));
}
}
OnClickListener buttonClick = new OnClickListener() {
public void onClick(View v) {
String idxStr = (String)v.getTag();
tv.setText(idxStr);
}
};
}
Solution 2
You must setContentView before start findViewById
setContentView(R.layout.main);
tv = (TextView) findViewById(R.id.text);
nenito
Updated on July 13, 2020Comments
-
nenito almost 4 years
I have a problem with getting the child's position of LinearLayout. First I'm adding dynamically a number of buttons and then I'm trying to return each child's index and display it into a TextView. Here I'm sharing code:
java source:
private String[] categories; private LinearLayout ll; private TextView tv; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); categories = getResources().getStringArray(R.array.categories); tv = (TextView) findViewById(R.id.text); ll = (LinearLayout) findViewById(R.id.hsvLinearLayout); for(int i = 0; i < categories.length; i++) { Button btn = new Button(this); btn.setText(categories[i]); btn.setOnClickListener(buttonClick); ll.addView(btn); } } OnClickListener buttonClick = new OnClickListener() { public void onClick(View v) { tv.setText(ll.indexOfChild(v)); } };
xml structure:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" > <HorizontalScrollView android:id="@+id/Footer" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scrollbars="none" android:fadingEdge="none" > <LinearLayout android:id="@+id/hsvLinearLayout" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" > </LinearLayout> </HorizontalScrollView> <TextView android:id="@+id/text" android:layout_width="fill_parent" android:layout_height="wrap_content" />
resources:
<string name="today">Today</string> <string name="life">Life</string> <string name="corner">Corner</string> <string name="banks">Banks</string> <string name="it">IT</string> <string name="fun">Fun</string> <array name="categories"> <item>@string/today</item> <item>@string/life</item> <item>@string/corner</item> <item>@string/banks</item> <item>@string/it</item> <item>@string/fun</item> </array>
The dynamically adding is fine, but the way I'm setting the OnClickListener produce some error. Any help will be useful! The purpose of that is if I want to add one or more button(s) to the HorizontalScrollView not to be necessary to edit many files, and just to go to sting.xml and create a new item into the categories-array!
This is what LogCat produced:
07-12 22:37:17.680: INFO/System.out(331): waiting for debugger to settle... 07-12 22:37:17.900: INFO/System.out(331): debugger has settled (1441) 07-12 22:37:20.870: INFO/ActivityManager(61): Displayed activity com.test/.TestDynam: 10203 ms (total 10203 ms) 07-12 22:37:25.552: WARN/ResourceType(331): No package identifier when getting value for resource number 0x00000000 07-12 22:37:26.871: DEBUG/dalvikvm(132): GC freed 190 objects / 8976 bytes in 901ms
To clarify - the application starts without any errors, but when I click on a button it produces this line from the above log:
07-12 22:37:25.552: WARN/ResourceType(331): No package identifier when getting value for resource number 0x00000000
And this is from debugger:
TestDynam [Android Application] DalvikVM[localhost:8611] Thread [<3> main] (Suspended (exception Resources$NotFoundException)) ViewRoot.handleMessage(Message) line: 1704 ViewRoot(Handler).dispatchMessage(Message) line: 99 Looper.loop() line: 123 ActivityThread.main(String[]) line: 4203 Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method] Method.invoke(Object, Object...) line: 521 ZygoteInit$MethodAndArgsCaller.run() line: 791 ZygoteInit.main(String[]) line: 549 NativeStart.main(String[]) line: not available [native method] Thread [<13> Binder Thread #2] (Running) Thread [<11> Binder Thread #1] (Running)
-
nenito almost 13 yearsI don't think this is the problem and why do you think I should call
setContentView()
beforefindViewById()
? -
Anh Tuan almost 13 yearssetContentView will inflate layout resource and create a ViewGroup represent that layout resource. From that ViewGroup, you can use findViewById to get child view.
-
nenito almost 13 yearsThe dynamically setting of the OnClickListener causes unexpected error, but I'm still new and I can't figure it out!
-
codeScriber almost 13 yearsfirst anh Tuan is write, trying to get view before setting content view will always bring you null. second if you would share your stacktrace it would make it easier to know what's the problem. Thrid take the findViewById out of the loop, you need it only once. Forth try to use ll instead of vg, most likly u get nullPointerException snce you never initalize vg.
-
codeScriber almost 13 yearsoh and one more thing :-) LinearLayout basically (basically!) doesn't change position of views unless you force it to, meaning if you add them before other views so if the view was empty you can be sure that each index is i = 0; and i +1 for each new item you add, in addition if you use more then 8-10 items i think ListView would be better option memory wise since Views gets recycled....
-
nenito almost 13 yearsthis is the Log of LogCat and is there a way to use horizontal ListView?
-
codeScriber almost 13 yearsi'm not sure, i think there was a thread about it... Gallery does just that but it's for images only...the logcat seems lacking, please on't post it as a commnet but as code sample in your original post, i don't see any Exceptions in what u just post...
-
nenito almost 13 yearsactually, this is the Log after the changes I've made, regarding your previous comments.
-
nenito almost 13 yearsI guess the way I'm adding a Button to the LinearLayout is problematic, but not sure.
exception Resources$NotFoundException
-
nenito almost 13 years...or
tv.setText(""+ll.indexOfChild(v));
anyway thanks a lot, such a small mistake!