Can't scroll ListView inside ListView in Android - android

While trying to create news feed in my app, I've created custom ListView Adapter. My single ListView item has an ImageView, WebView and ListView. So I have a ListView inside a ListView. The problem is, when I try to scroll the inner ListView, the outer ListView is being scrolled. What should I change to avoid the problem?
My custom adapter:
public class TestCustomAdapter extends BaseAdapter {
private List<String> imageNames = null;
private List<String> descriptions = null;
private List<String> innerLVitems = null;
private LayoutInflater mInflater;
private Context context;
public FirstFragmentLVAdapter(Context context, List<String> imageNames, List<String> descriptions, List<String> innerLVitems) {
this.imageNames = imageNames;
this.descriptions = descriptions;
this.innerLVitems = innerLVitems;
this.context = context;
mInflater = LayoutInflater.from(context);
}
public int getCount() {
return innerLVitems.size();
}
public Object getItem(int position) {
List <String> returnedList = new ArrayList<>();
returnedList.add(imageNames.get(position));
returnedList.add(descriptions.get(position));
returnedList.add(innerLVitems.get(position));
return returnedList;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.firstfragment_listview_item, null);
holder = new ViewHolder();
holder.image = (ImageView) convertView.findViewById(R.id.eventImage);
holder.description = (WebView) convertView.findViewById(R.id.eventDescriptionWV);
holder.LV = (ListView) convertView.findViewById(R.id.LV);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.image.setImageResource(context.getResources().getIdentifier(imageNames.get(position), "drawable", context.getPackageName()));
String webViewText = "<html><body><p align=\"justify\">"+
descriptions.get(position)+"</p></body></html>";
holder.description.loadDataWithBaseURL(null, webViewText, "text/html", "UTF-8", null);
String [] items = innerLVitems.get(position).split("\\s*,\\s*");
ArrayAdapter<String> adapter = new ArrayAdapter<String>(context,
android.R.layout.simple_list_item_1, android.R.id.text1, items);
holder.LV.setAdapter(adapter);
return convertView;
}
static class ViewHolder {
ImageView image;
WebView description;
ListView LV;
}
}
My listview item:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp">
<ImageView
android:id="#+id/eventImage"
android:layout_width="wrap_content"
android:layout_height="125dp"
app:srcCompat="#drawable/autumn" />
<WebView
android:id="#+id/eventDescriptionWV"
android:layout_width="match_parent"
android:layout_height="220dp"
android:layout_below="#id/eventImage"></WebView>
<TextView
android:id="#+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/eventDescriptionWV"
android:text="Text" />
<ListView
android:divider="#null"
android:dividerHeight="0dp"
android:id="#+id/LV"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_below="#id/label" />

To use 2 nested ListViews you sh to use an ExpandableListView : https://developer.android.com/reference/android/widget/ExpandableListView.html.
Using 2 ListViews the Android will always apply the scroll on the first one it finds. The ExpandableListView component is specific for working with sublists within lists.

I was able to find a solution for my case. I needed to add this line to the inner ListView XML:
android:nestedScrollingEnabled="true"
This only works only for Lollipop and up though.

You may want to use RecyclerViewwith NestedScrollView and turn off RecyclerView's nested scrolling. This way you can have multiple scrollable items along same orientation.

Related

How to create two different LinearLayout in a same ListView?

i want to combine two LinearLayout, both have different TextView arrangement in them, in a single ListView. so the final look should be like below:
and i run it with my code, but the app wouldn't start. below are my code.
Activity class:
public class MainActivity extends Activity {
// Create list of items
String[] publicModeItems = {
"AAAAA",
"BBBBB"
};
String[] publicModeParameters = {
"YES",
"NO"
};
String[] publicModeResetExe = {
"CCCCC",
"DDDDD"
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
populateListView();
}
private void populateListView() {
CustomList adapter1 = new CustomList(this, publicModeItems, publicModeParameters);
// Build adapter
ArrayAdapter<String> adapter2 = new ArrayAdapter<String>(
this, // context for the activity
R.layout.text_view_test, // layout to use (create)
publicModeResetExe); // items to display
// Configure the list view
ListView list = (ListView) findViewById(R.id.PublicModeListView);
list.setAdapter(adapter1);
list.setAdapter(adapter2);
}
private class CustomList extends ArrayAdapter<String> {
private final Activity context;
private final String[] publicModeItems;
private final String[] publicModeParameters;
public CustomList(Activity context,
String[] publicModeItems,
String[] publicModeParameters) {
super(context, R.layout.text_views_1, publicModeItems);
this.context = context;
this.publicModeItems = publicModeItems;
this.publicModeParameters = publicModeParameters;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater layoutinflater = context.getLayoutInflater();
View rowView = layoutinflater.inflate(R.layout.text_views_1, null, true);
TextView txtPublicModeItems = (TextView) rowView.findViewById(R.id.PublicModeItems);
TextView txtPublicModeParameters = (TextView) rowView.findViewById(R.id.PublicModeParameters);
txtPublicModeItems.setText(publicModeItems[position]);
txtPublicModeParameters.setText(publicModeParameters[position]);
return rowView;
}
}
}
text_views_1 xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/PublicModeLayoutForTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/PublicModeItems"
android:layout_width="200sp"
android:layout_height="wrap_content"
android:textColor="#drawable/text_color_change" />
<TextView
android:id="#+id/PublicModeOpenBracket"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="["
android:textColor="#drawable/text_color_change" />
<TextView
android:id="#+id/PublicModeParameters"
android:layout_width="100sp"
android:layout_height="wrap_content"
android:gravity="end"
android:textColor="#drawable/text_color_change" />
<TextView
android:id="#+id/PublicModeCloseBracket"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="]"
android:textColor="#drawable/text_color_change" />
</LinearLayout>
text_view_test xml:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="#drawable/text_color_change" >
</TextView>
activity_main xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/PublicModeListViewLayout01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/black"
android:baselineAligned="true"
android:orientation="vertical"
tools:context="com.example.mycalendar.MainActivity" >
<LinearLayout
android:id="#+id/PublicModeListViewLayout02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#drawable/custom_border"
android:padding="5dp" >
<ListView
android:id="#+id/PublicModeListView"
android:layout_width="308dp"
android:layout_height="wrap_content"
android:choiceMode="singleChoice"
android:listSelector="#color/yellow"
android:smoothScrollbar="true" >
</ListView>
</LinearLayout>
</LinearLayout>
Problem : I just run my code just now, and only 'CCCCC' and 'DDDDD' is showing. so do you have any idea on this?
You should inherit your list adapter from BaseAdapter rather than ArrayAdapter.
Rewrite adapter's getView() method to inflate layout according position, like below.
public View getView(int position, View convertView, ViewGroup parent) {
...
View rootView = null;
if (position == 0 || position == 1) {
rootView = layoutinflater.inflate(R.layout.text_views_1, null, true);
} else {
rootView = layoutinflater.inflate(R.layout.text_views, null, true);
}
...
return rootView;
}
You set the list adapter twice
list.setAdapter(adapter1);
list.setAdapter(adapter2);
in this case the current adapter is the second, not them both.
Use ListView with SimpleAdapter or a custom adapter and that will solve all your problems, check out this for SimpleAdapter tutorial to learn a the basics and this tutorial to learn how you can make multiple views instead of just 1. This tutorial is about creating custom adapter
BTW, I have few comments on your code and xml layout
First, there is no need for 2 TextViews for your bracket, you can easily add them programmatically to the String[] or even to YES/NO TextView.
Second, You're not using a ViewHolder in your CustomList adapter and this is not a good practice as every time you scroll your list, it creates new view although it can use already existing one.
I already solve this problem. but it seems not so convenient to use this method.
public class PublicModeActivity extends Activity {
// Create list of items
String[] publicModeItems = {
"AAAAA",
"BBBBB"
};
String[] publicModeParameters = {
"YES",
"NO"
String[] publicModeResEx = {
"",
"",
"CCCCC",
"DDDDD"
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
populateListView();
}
private void populateListView() {
CustomList adapter = new CustomList(this, publicModeItems, publicModeParameters, publicModeResEx);
// Configure the list view
ListView list = (ListView) findViewById(R.id.PublicModeListView);
list.setAdapter(adapter);
}
private class CustomList extends BaseAdapter {
private final Activity context;
private final String[] publicModeItems;
private final String[] publicModeParameters;
private final String[] publicModeResEx;
public CustomList(Activity context,
String[] publicModeItems,
String[] publicModeParameters,
String[] publicModeResEx) {
super();
this.context = context;
this.publicModeItems = publicModeItems;
this.publicModeParameters = publicModeParameters;
this.publicModeResEx = publicModeResEx;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater layoutinflater = context.getLayoutInflater();
View rowView = null;
Log.i("PublicModeActivity", "" + position);
if (position < 2) {
rowView = layoutinflater.inflate(R.layout.text_views_1, null, true);
TextView txtPublicModeItems = (TextView) rowView.findViewById(R.id.PublicModeItems);
TextView txtPublicModeParameters = (TextView) rowView.findViewById(R.id.PublicModeParameters);
txtPublicModeItems.setText(publicModeItems[position]);
txtPublicModeParameters.setText(publicModeParameters[position]);
} else {
rowView = layoutinflater.inflate(R.layout.text_view_test, null, true);
TextView txtPublicModeResEx = (TextView) rowView.findViewById(R.id.PublicModeResEx);
txtPublicModeResEx.setText(publicModeResEx[position]);
}
return rowView;
}
#Override
public int getCount() {
return 4;
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
}
}
I need to put that blank string "", to match the number of row with the upper layout (text_views_1) even-though those blank string are use in different layout. so it is not so convenient especially when you want to display so many data. If someone here have much simpler method than this. feel free to share with me/us. i'm eager to learn. thank you!

How to implement list view with two parallel imageview in a row

Well I do not know what should be the proper title for the question , but my problem is quite amazing, do not know is it possible or not. Here is my question
I have series of images and I want to set them in a ListView. following is a ListView row Xml.(named anim_list_row)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="100"
>
<ImageView
android:layout_width="0dp"
android:layout_height="350dp"
android:scaleType="fitXY"
android:id="#+id/iv_dummy_left"
android:layout_marginLeft="5dp"
android:layout_weight="50"/>
<ImageView
android:layout_width="0dp"
android:layout_height="350dp"
android:scaleType="fitXY"
android:id="#+id/iv_dummy_right"
android:layout_weight="50"
android:layout_marginRight="5dp"/>
</LinearLayout>
in this you can see that I want to set the 2 different images in two different let say left and right ImageView. Following is my adapter class
public class MListAdapter extends BaseAdapter {
private Context context;
private ArrayList<AnimListItems> mAnimListItems;
public MListAdapter(Context context, ArrayList<AnimListItems> mAnimListItems){
this.context = context;
this.mAnimListItems = mAnimListItems;
}
#Override
public int getCount() {
return mAnimListItems.size();
}
#Override
public Object getItem(int position) {
return navDrawerItems.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.anim_list_row, null);
}
ImageView imgIconLeft = (ImageView) convertView.findViewById(R.id.iv_dummy_left);
ImageView imgIconRight = (ImageView) convertView.findViewById(R.id.iv_dummy_right);
//TextView txtTitle = (TextView) convertView.findViewById(R.id.title);
imgIconLeft.setImageResource(navDrawerItems.get(position).getIcon());
//if I do not do +1 here it sets same image to both left and right ImageView
imgIconRight.setImageResource(navDrawerItems.get(position+1).getIcon());
// txtTitle.setText(navDrawerItems.get(position).getTitle());
return convertView;
}
}
so here is problem this list view is working but it is assigning the same images to both ImageView in the row. and if I do +1 as following
imgIconRight.setImageResource(navDrawerItems.get(position+1).getIcon())
then it helps in changing the image view at right side in the row, but the 2nd row repeat the image in its first imageview (I mean the image in the left ImageView of the 2nd row is same as the image in right ImageView of first row.)
So what is a solution of
Repeating images in a rows.
And How can I get each ImageView id and its resourceid of the image so that I can come to know which image has been clicked. And then I can able to set that image into another activity's ImageView. I mean I wanted to know which image has been clicked by the user , so I want to set same image in the ImageView of other activity.
Hello If you want to user one single array then i have made one demo example for your problem quickly i think it will help you.
MainActivity.java
public class MainActivity extends ActionBarActivity {
Item item;
ArrayList<Object> obj = new ArrayList<Object>();
MListAdapter adapter;
ListView lv;
int[] arrEnabledImageIds = new int[] { R.drawable.ic_launcher,
R.drawable.ic_delete_icon, R.drawable.ic_delete_icon,
R.drawable.ic_launcher, R.drawable.ic_delete_icon,
R.drawable.ic_launcher };
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.listView1);
for (int i = 0; i < arrEnabledImageIds.length; i++) {
Item itemInfo = new Item();
itemInfo.image1 = arrEnabledImageIds[i];
i++;
itemInfo.image2 = arrEnabledImageIds[i];
obj.add(itemInfo);
}
adapter = new MListAdapter(this, R.layout.row, obj);
lv.setAdapter(adapter);
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
Item.java
public class Item implements Serializable {
public static final long serialVersionUID = 1L;
public int image1;
public int image2;
}
row.xml
<?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="horizontal" >
<ImageView
android:id="#+id/ivLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher" />
<ImageView
android:id="#+id/ivRight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher" />
</LinearLayout>
MListAdapter.java
public class MListAdapter extends ArrayAdapter<Object> {
private Context context;
int resId;
private ArrayList<Object> mAnimListItems;
public MListAdapter(Context context, int textViewResourceId,
ArrayList<Object> mAnimListItems) {
super(context, textViewResourceId, mAnimListItems);
this.resId = textViewResourceId;
this.context = context;
this.mAnimListItems = mAnimListItems;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(resId, null);
}
ImageView imgIconLeft = (ImageView) convertView
.findViewById(R.id.ivLeft);
ImageView imgIconRight = (ImageView) convertView
.findViewById(R.id.ivRight);
// TextView txtTitle = (TextView) convertView.findViewById(R.id.title);
Item item = (Item) mAnimListItems.get(position);
imgIconLeft.setImageResource(item.image1);
// if I do not do +1 here it sets same image to both left and right
// ImageView
imgIconRight.setImageResource(item.image2);
// txtTitle.setText(navDrawerItems.get(position).getTitle());
return convertView;
}
}
try to use two different array/arraylist to store left and rightside images seprately.
settag as l+position for left image
settag as r+position for right image
you can identify the clicked image by
imgIconLeft.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(v.getTag.toString().contains("l"){
// then it's a left button.
String position=v.getTag.toString().subString(1,v.getTag.toString().length()-1);
// to get position
}
});

Android text and bitmap in menu items

In my app, I am creating a dynamic list of items using
shopsNameList = new ArrayList<String>();
// Create The Adapter
ArrayAdapter<String> arrayAdapter =
new ArrayAdapter<String>(ShopsListActivity.this, android.R.layout.simple_list_item_1, shopsNameList);
I would like to have a text and an image in each element of the list, not a simple text.
I defined a listviewitem.xml layout
<?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" >
<ImageView
android:id="#+id/listitemimage"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="#raw/shop" />
<TextView
android:id="#+id/textview"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Test" />
</LinearLayout>
and tried
ArrayAdapter<String> arrayAdapter =
new ArrayAdapter<String>(ShopsListActivity.this, R.layout.listviewitem, shopsNameList);
but my app crashes when I enter the list.
I am inside an activity creted with
super.onCreate(saveInstanceState);
setContentView(R.layout.shopslist);
// Get the reference of ListView
ListView shopsList=(ListView)findViewById(R.id.listShops);
shopsNameList = new ArrayList<String>();
shopElements = new ArrayList<ShopElement>();
You need to create custom adapter for your ListView:
public class CustomAdapter extends ArrayAdapter<String>{
Context context;
public CustomAdapter(Context context, List< String > objects)
{
super( context, R.layout.listviewitem, objects );
this.context = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ShopListHolder holder = null;
if(convertView == null)
{
LayoutInflater inflater = LayoutInflater.from( context );
convertView = inflater.inflate(R.layout.listviewitem, parent, false);
holder = new ShopListHolder();
holder.imgIcon = (ImageView)convertView.findViewById(R.id.listitemimage);
holder.txtTitle = (TextView)convertView.findViewById(R.id.textview);
convertView.setTag(holder);
}
else
{
holder = (ShopListHolder )convertView.getTag();
}
holder.txtTitle.setText(getItem( position ));
return convertView;
}
class ShopListHolder
{
ImageView imgIcon;
TextView txtTitle;
}
}

Can't find TextView in recursive custom Listview adapter

I created this class called GeoArea, which is suppose to store "Geographical Area" that have children Geographical Areas, this is fairly strait foward:
public class GeoArea {
public String id;
public String name;
public List<GeoArea> subGeoAreas;
public GeoArea parentGeoArea;
public GeoArea(String id) {
this.id = id;
name = id;
subGeoAreas = new LinkedList<GeoArea>();
}
#Override
public String toString() {
return name;
}
}
I have created the following Layout to render it on Android, the idea here is to for each GeoArea to recursively render it self and then it's children GeoArea in a listView:
//layout_geo_area.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/txtGeoAreaName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:gravity="left"
android:text="Geo Area Name"
android:textAppearance="?android:attr/textAppearanceLarge" />
<ListView
android:id="#+id/listViewChildGeoAreas"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/txtGeoAreaName"
android:gravity="left" >
</ListView>
</RelativeLayout>
This is my adapter I created for GeoArea to be displayed in a listView:
public class AdapterGeoArea extends ArrayAdapter<GeoArea>{
private ArrayList<GeoArea> _myGeoArea;
private Context _myContext;
LayoutInflater _inflater;
public AdapterGeoArea(Context context, ArrayList<GeoArea> myGeoArea) {
super(context, 0, myGeoArea);
_myGeoArea = myGeoArea;
_inflater = LayoutInflater.from(context);
_myContext = context;
}
public int getCount() {
return _myGeoArea.size();
}
public View getView(int position, View convertView, ViewGroup parent) {
GeoAreaLayoutHolder holder;
if (convertView == null) {
convertView = _inflater.inflate(R.layout.layout_geo_area,parent,false);
holder = new GeoAreaLayoutHolder();
holder.txtGeoAreaName = (TextView)convertView.findViewById(R.id.txtGeoAreaName);
holder.txtGeoAreaName.setTag(convertView);
holder.listViewChildGeoAreas = (ListView)convertView.findViewById(R.id.listViewChildGeoAreas);
holder.listViewChildGeoAreas.setTag(convertView);
} else {
holder = (GeoAreaLayoutHolder) convertView.getTag();
}
GeoArea curGeoArea = _myGeoArea.get(position);
holder.txtGeoAreaName.setText(curGeoArea.name);
if(curGeoArea.subGeoAreas.size()>0){
ArrayList<GeoArea> testList = new ArrayList<GeoArea>();
AdapterGeoArea adapter = new AdapterGeoArea(_myContext, testList);
for(GeoArea childGeoArea:curGeoArea.subGeoAreas){
testList.add(childGeoArea);
}
holder.listViewChildGeoAreas.setAdapter(adapter);
}
return convertView;
}
static class GeoAreaLayoutHolder {
public TextView txtGeoAreaName;
public ListView listViewChildGeoAreas;
}
}
And here is my Activity that I am using to set it all up:
public class ActivityGeoAreas extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_geo_area);
GeoArea.searchTerm = "Bar & Grill";
GeoArea torontoArea = new GeoArea("cityOfToronto");
ArrayList<GeoArea> testList = new ArrayList<GeoArea>();
testList.add(torontoArea);
AdapterGeoArea adapter = new AdapterGeoArea(this, testList);
ListView lv = (ListView) findViewById(R.id.listViewChildGeoAreas);
lv.setAdapter(adapter);
}
}
When I try to run it, I get the error nullPointerException on the line:
holder.txtGeoAreaName.setText(curGeoArea.name);
What am I doing wrong?
You may want to check ExpandableListView may suit your needs better
http://developer.android.com/reference/android/widget/ExpandableListView.html
An example # http://www.androidhive.info/2013/07/android-expandable-list-view-tutorial/
Continuing from my previous answer to your question ( i though that solved your problem)
To display just name in your listview
list_row.xml // this is the layout with textview to be inflated in getView.
Each row will have textview
<?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" >
<TextView
android:id="#+id/textGeoArea"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="14dp"
android:text="Choose Area"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
layout_geo_area.xml // with only listview no textview
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:id="#+id/listViewChildGeoAreas"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:gravity="left" >
</ListView>
</RelativeLayout>
Now your adapter class
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_row,parent,false);
// inflate list_row.xml with textview
holder = new ViewHolder();
holder.tv = (TextView)convertView.findViewById(R.id.textGeoArea);
holder.setTag(convertView);
}
else {
holder = (ViewHolder) convertView.getTag();
}
GeoArea curGeoArea = _myGeoArea.get(position);
holder.tv.setText(curGeoArea.name);
return convertView;
}
static class ViewHolder // use a view holder for smooth scrolling an performance
{
TextView tv;
}
You have a custom adapter.
public class AdapterGeoArea extends ArrayAdapter<GeoArea>{
Now you set the adapter to listview like below
AdapterGeoArea adapter = new AdapterGeoArea(this, testList);
ListView lv = (ListView) findViewById(R.id.listViewChildGeoAreas);
lv.setAdapter(adapter);
So why do you need the below. remove these
if(curGeoArea.subGeoAreas.size()>0){
ArrayList<GeoArea> testList = new ArrayList<GeoArea>();
AdapterGeoArea adapter = new AdapterGeoArea(_myContext, testList);
for(GeoArea childGeoArea:curGeoArea.subGeoAreas){
testList.add(childGeoArea);
}
holder.listViewChildGeoAreas.setAdapter(adapter);

android gridview slow scrolling

I have an android activity with a gridview, each cell contains a textview with a single character (so there are around 60-70 characters/cells on the screen at a time). The scrolling of the gridview is unacceptably slow and unsmooth. I tried replacing the gridview with a listview, and the scrolling of the listview is much faster. How can i speed this up?
The activity layout is:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<GridView
android:id="#+id/gridView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="56dp"
android:numColumns="auto_fit" >
</GridView>
</LinearLayout>
And inside each cell is this layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textSize="40sp" />
</LinearLayout>
And the code for the activity is:
public class TestGridActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.grid_activity);
GridView gridView = (GridView) findViewById(R.id.gridView1);
ArrayList<Map<String, String>> list = getData();
SimpleAdapter arrayAdapter = new SimpleAdapter(this, list,
R.layout.grid_layout, new String[] { "literal"},
new int[] { R.id.textView1});
gridView.setAdapter(arrayAdapter);
}
}
edit: pks asking to post adapter code, the above code I have used a generic simpleAdapter, but i have tried a custom view, which didn't help.
public class GridAdapter extends BaseAdapter {
private Context context;
private ArrayList<Map<String, String>> list;
private LayoutInflater inflater;
public static class ViewHolder {
TextView textView1;
int position;
}
public GridAdapter(Context c, ArrayList<Map<String, String>> l) {
context = c;
list = l;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return list.size();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null){
convertView = inflater.inflate(R.layout.grid_layout, null);
holder = new ViewHolder();
holder.textView1 = (TextView) convertView.findViewById(R.id.textView1);
holder.position = position;
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.textView1.setText(list.get(position).get("character"));
return convertView;
}
}
I've also tried creating all the views in advance, and that didn't help scrolling speed.

Categories

Resources