P
P
Pyjamec2011-04-26 14:53:22
Android
Pyjamec, 2011-04-26 14:53:22

Transition between Activity in ActivityGroup (in tabs)?

When switching between activities (using ActivityGroup in tabs), an error occurs:

04-26 08:46:04.599: ERROR/AndroidRuntime(992): java.lang.StackOverflowError<br/>
04-26 08:46:04.599: ERROR/AndroidRuntime(992): at android.text.Layout.measureText(Layout.java:1601)<br/>
04-26 08:46:04.599: ERROR/AndroidRuntime(992): at android.text.Layout.getLineMax(Layout.java:655)<br/>
04-26 08:46:04.599: ERROR/AndroidRuntime(992): at android.text.Layout.draw(Layout.java:311)<br/>
04-26 08:46:04.599: ERROR/AndroidRuntime(992): at android.text.BoringLayout.draw(BoringLayout.java:365)<br/>
04-26 08:46:04.599: ERROR/AndroidRuntime(992): at android.widget.TextView.onDraw(TextView.java:4052)<br/>
04-26 08:46:04.599: ERROR/AndroidRuntime(992): at android.view.View.draw(View.java:6535)<br/>
04-26 08:46:04.599: ERROR/AndroidRuntime(992): at android.view.ViewGroup.drawChild(ViewGroup.java:1531)<br/>
04-26 08:46:04.599: ERROR/AndroidRuntime(992): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)<br/>
 ...<br/>

the code:
...<br/>
private ListView _lv;<br/>
...<br/>
@Override<br/>
 public void onCreate(Bundle savedInstanceState) {<br/>
 super.onCreate(savedInstanceState);<br/>
 ...<br/>
 List cats = Category.getAllCategories(this);<br/>
 _lv = (ListView)findViewById(android.R.id.list);<br/>
 _lv.setAdapter(new CategoryAdapter(getBaseContext(),R.layout.list_item_layout, cats)); <br/>
 _lv.setOnItemClickListener(new ListClickListener());<br/>
 ...<br/>
}<br/>
public void replaceContentView(String id, Intent newIntent/*,int result*/) {<br/>
 View view = getLocalActivityManager().startActivity(id,newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)) <br/>
 .getDecorView(); <br/>
 this.setContentView(view);<br/>
 } <br/>
<br/>
<br/>
Нужный кусок взят отсюда: <a href="http://www.gamma-point.com/content/android-how-have-multiple-activities-under-single-tab-tabactivity">www.gamma-point.com/content/android-how-have-multiple-activities-under-single-tab-tabactivity</a><br/>
<br/>
Код лэйаутов:<br/>
<code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;<br/>
&lt;LinearLayout<br/>
 xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;<br/>
 android:id=&quot;@+id/recipes_in_cat_list&quot;<br/>
 android:orientation=&quot;vertical&quot;<br/>
 android:layout_width=&quot;fill_parent&quot;<br/>
 android:layout_height=&quot;fill_parent&quot;&gt;<br/>
 &lt;LinearLayout<br/>
 android:layout_width=&quot;fill_parent&quot;<br/>
 android:layout_height=&quot;wrap_content&quot;<br/>
 android:gravity=&quot;left&quot; <br/>
 android:background=&quot;@drawable/tab_upper_bar&quot;&gt;<br/>
 &lt;Button<br/>
 android:id=&quot;@+id/back_to_cats_button&quot;<br/>
 android:layout_width=&quot;wrap_content&quot;<br/>
 android:layout_height=&quot;wrap_content&quot;<br/>
 android:layout_marginLeft=&quot;5dip&quot;<br/>
 android:background=&quot;@drawable/android_info_button&quot; /&gt;<br/>
 </code><br/>
 &lt;ListView<br/>
 android:id=&quot;@android:id/list&quot;<br/>
 android:layout_width=&quot;fill_parent&quot;<br/>
 android:layout_height=&quot;fill_parent&quot;<br/>
 android:gravity=&quot;center&quot;<br/>
 android:divider = &quot;#00000000&quot;<br/>
 android:cacheColorHint=&quot;#00000000&quot; /&gt;<br/>

and layout for the list:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=" schemas.android.com/apk/res/android "
android:orientation="horizontal"
android: layout_width="fill_parent"
android:layout_height="40dip"
android:layout_weight="1"
android:padding = "10dip"
android:background ="@drawable/list_item_bg"
android:layout_centerHorizontal="true">
<ImageView
android:id= "@+id/recipe_list_left"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:src="@drawable/list_left"
android:layout_weight="0" />
<TextView
android:id="@+id/recipe_list_text"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
style = "@style/RecipeListText"
android:layout_weight="1"
android:gravity="center_horizontal" />
< ImageView
android:id="@+id/recipe_list_right"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:src="@drawable/list_right" android: layout_weight
="0" />
there is such an error and in which direction to dig?
Too much nesting of views?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
A
Assoulter, 2011-04-27
@Assoulter

In general, I meant, post the project archive, if it is not secret, somewhere for download, or on some github :) Understand code snippets to find what causes stack overflow, without debugging and reading logs , hard. However, there are a few notes:

  1. using nested LinearLayouts in large numbers instead of RelativeLayouts is costly in terms of memory and performance. When a certain number of nodes in the Views hierarchy is reached, a stack overflow is possible. Especially relevant for versions 1.5-1.6. You should get rid of LinearLayout and optimize templates, as I wrote above.
  2. did not understand a little why you use destroyDrawingCache. Read about speeding up the listview using the ViewHolder pattern here or here
  3. the reason for calling the context with getBaseContext() is not clear. Activity already has a context, just use this.
  4. not related to the problem, but still. Event handlers, in order not to fence extra code and improve readability, can be added to anonymous functions, for example
    _btBack.setOnClickListener(new OnClickListener(){
    @Override
    public void onClick(View v){
    //blablabla
    }
    });

A
Assoulter, 2011-04-27
@Assoulter

Alas, little is clear from the above code. The example from the site works with a bang, so you have a problem. It's possible that using too many LinearLayouts instead of RelativeLayouts, coupled with not caching your Views in the CategoryAdapter's getView method (I don't see how you implemented it), is causing a stack overflow. Either try to optimize your templates, or post a more complete version of the project somewhere for further help.

P
Pyjamec, 2011-04-27
@Pyjamec

Promised code:
CategoryAdapter in full:
public class CategoryAdapter extends ArrayAdapter {
private List _items;
public CategoryAdapter(Context context, int textViewResourceId,
List items) {
super(context, textViewResourceId, items);
_items = items;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.list_item_layout, null);
v.destroyDrawingCache();
}
Category cat = _items.get(position);
if (cat != null) {
TextView listText = (TextView) v.findViewById(R.id.list_text);
listText.setText(cat.getName());
}
return v;
}
@Override
public Category getItem(int position) {
return _items.get(position);
}
}
Отсюда(таб) мы начинаем переход:
public class RecipeTab extends ActivityGroup {
private ListView _lv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.recipe_tab);
List cats = Category.getAllCategories(this);
_lv = (ListView)findViewById(android.R.id.list);
_lv.setAdapter(new CategoryAdapter(getBaseContext(),R.layout.list_item_layout, cats));
_lv.setOnItemClickListener(new ListClickListener());
}
public void replaceContentView(String id, Intent newIntent/*,int result*/) {
View view = getLocalActivityManager().startActivity(id,newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))
.getDecorView();
this.setContentView(view);
}
...
код обработчика при нажатии на элемент списка:

private class ListClickListener implements ListView.OnItemClickListener {
public void onItemClick(AdapterView parent, View v, int position, long l){
Category selectedItem = (Category)_lv.getItemAtPosition(position);
int catId = selectedItem.getId();
Intent intent = new Intent(RecipeTab.this,CategoryActivity.class);
Bundle bundle = new Bundle();
bundle.putInt("catId", catId);
intent.putExtras(bundle);
replaceContentView("categoryActivity", intent);
}
}
...
}

В данный активити мы переходим и потом обратно на RecipeTab
public class CategoryActivity extends Activity{
private ListView _lv;
private Button _btBack;
private LocalActivityManager lam;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.category_activity_layout);
_btBack = (Button)findViewById(R.id.back_to_cats_button);
_btBack.setOnClickListener(new BackButtonListener());
List recps = Recipe.getRecipesByCatId(this, catId);
_lv = (ListView)findViewById(android.R.id.list);
_lv.setAdapter(new RecipeAdapter(getBaseContext(),R.layout.recipe_list_item, recps));
}
и код обработчика:
class BackButtonListener implements View.OnClickListener {
public void onClick(View v){
Intent intent = new Intent(v.getContext(), RecipeTab.class);
RecipeTab parentActivity = (RecipeTab)getParent();
parentActivity.replaceContentView("recipeTab", intent);
}
}

Код лэйаутов для CategoryAcivity и элемента списка находится в вопросе выше.
По-моему, много букв получилось, так что остальное по требованию.
Кстать, кнопка назад в эмуляторе почему-то переходит не на предидущий активити, а на рабочий стол.
Почему так?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question