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!
Related
I am new to android programming and this task is really need for my school project. Please kindly help me.
I've string array List - (retrieved from csv)
list = new ArrayList<>(Arrays.asList("111,222,333,444,555,666".split(",")));
myList.setAdapter(new ArrayAdapter<String>(getActivity(),R.layout.cell,list));
The result is showing only line by line text of arrayList. I want to add button to each generated line by line to delete clicked row.
Please how can I do this. Thank you for understanding my problem.
You have to create a custom layout xml which having a single item then you will add your button to this layout along with any other items.
CustomLayout.Xml
<?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/tvContact"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textStyle="bold" />
<Button
android:id="#+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Call" />
</RelativeLayout>
Now after creating custom item layout you need listview which holds all items.
MainActivity.xml
.
.
<ListView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
.
.
Now in java file just set adapter with our custom layout xml
.
.
list = new ArrayList<String>(Arrays.asList("111,222,333,444,555,666".split(",")));
listview.setAdapter(new MyCustomAdapter(list, context) );
.
.
Custom adapter Class
public class MyCustomAdapter extends BaseAdapter implements ListAdapter {
private ArrayList<String> list = new ArrayList<String>();
private Context context;
public MyCustomAdapter(ArrayList<String> list, Context context) {
this.list = list;
this.context = context;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int pos) {
return list.get(pos);
}
#Override
public long getItemId(int pos) {
return list.get(pos).getId();
//just return 0 if your list items do not have an Id variable.
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.CustomLayout, null);
}
//Handle TextView and display string from your list
TextView tvContact= (TextView)view.findViewById(R.id.tvContact);
tvContact.setText(list.get(position));
//Handle buttons and add onClickListeners
Button callbtn= (Button)view.findViewById(R.id.btn);
callbtn.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
//do something
}
});
addBtn.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
//do something
notifyDataSetChanged();
.
}
});
return view;
}
}
We have need ListviewActivity for listing your data
SchoolAdapter which is custom adapter to inflate each individual row
activity_listview which is layout for ListviewActivity
view_listview_row which is required for each individual row
Now create all file as below
For ListviewActivity,
public class ListviewActivity extends AppCompatActivity {
private ListView mListview;
private ArrayList<String> mArrData;
private SchoolAdapter mAdapter;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_listview);
mListview = (ListView) findViewById(R.id.listSchool);
// Set some data to array list
mArrData = new ArrayList<String>(Arrays.asList("111,222,333,444,555,666".split(",")));
// Initialize adapter and set adapter to list view
mAdapter = new SchoolAdapter(ListviewActivity.this, mArrData);
mListview.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
}
For SchoolAdapter,
public class SchoolAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<String> mArrSchoolData;
public SchoolAdapter(Context context, ArrayList arrSchoolData) {
super();
mContext = context;
mArrSchoolData = arrSchoolData;
}
public int getCount() {
// return the number of records
return mArrSchoolData.size();
}
// getView method is called for each item of ListView
public View getView(int position, View view, ViewGroup parent) {
// inflate the layout for each item of listView
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.view_listview_row, parent, false);
// get the reference of textView and button
TextView txtSchoolTitle = (TextView) view.findViewById(R.id.txtSchoolTitle);
Button btnAction = (Button) view.findViewById(R.id.btnAction);
// Set the title and button name
txtSchoolTitle.setText(mArrSchoolData.get(position));
btnAction.setText("Action " + position);
// Click listener of button
btnAction.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Logic goes here
}
});
return view;
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}}
For activity_listview,
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#D1FFFF"
android:orientation="vertical">
<ListView
android:id="#+id/listSchool"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:divider="#0000CC"
android:dividerHeight="0.1dp"></ListView>
For view_listview_row,
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="7.5dp"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingTop="7.5dp">
<TextView
android:id="#+id/txtSchoolTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="2dp"
android:text="TextView"
android:textColor="#android:color/black"
android:textSize="20dp" />
<Button
android:id="#+id/btnAction"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="Click Me" />
At last but not least, do not forgot to add your activity in manifest.xml
Create a custom list view in another file with the only content of each item in the list.
Then create a Custom Adapter extending BaseAdapter and bind it.
Please refer to this website for example.
https://looksok.wordpress.com/tag/listview-item-with-button/
OR
http://www.androidhive.info/2012/02/android-custom-listview-with-image-and-text/
I've read various SO threads on the topic but none of them seem to apply to my code.
I'm trying to populate a fragment with a ListView with my custom NearbyAdapter. However, my getView() method never gets called (as demonstrated by my logs not showing up). The view itself seems to be appropriately attached to my fragment, as demonstrated by the button in the view showing up, but not the ListView.
Relevant NearbyListFragment.java code:
public class NearbyListFragment extends ListFragment {
private int mImageSize;
private boolean mItemClicked;
private NearbyAdapter mAdapter;
private List<Place> places;
private LatLng mLatestLocation;
private static final String TAG = "NearbyListFragment";
public NearbyListFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d(TAG, "NearbyListFragment created");
View view = inflater.inflate(R.layout.fragment_nearby, container, false);
return view;
}
//TODO: Do asynchronously?
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
//Load from data source (NearbyPlaces.java)
mLatestLocation = ((NearbyActivity) getActivity()).getmLatestLocation();
//FIXME: Hardcoding mLatestLocation to Michigan for testing
//mLatestLocation = new LatLng(44.182205, -84.506836);
places = loadAttractionsFromLocation(mLatestLocation);
mAdapter = new NearbyAdapter(getActivity(), places);
ListView listview = (ListView) view.findViewById(R.id.listview);
//setListAdapter(mAdapter);
listview.setAdapter(mAdapter);
Log.d(TAG, "Adapter set to ListView");
mAdapter.notifyDataSetChanged();
}
private class NearbyAdapter extends ArrayAdapter {
public List<Place> placesList;
private Context mContext;
public NearbyAdapter(Context context, List<Place> places) {
super(context, R.layout.item_place);
mContext = context;
placesList = places;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
Place place = (Place) getItem(position);
//FIXME: This never gets called
Log.d(TAG, "Place " + place.name);
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_place, parent, false);
}
// Lookup view for data population
TextView tvName = (TextView) convertView.findViewById(R.id.tvName);
TextView tvDesc = (TextView) convertView.findViewById(R.id.tvDesc);
// Populate the data into the template view using the data object
tvName.setText(place.name);
tvDesc.setText(place.description);
// Return the completed view to render on screen
return convertView;
}
#Override
public long getItemId(int position) {
return position;
}
The layout file of the fragment, fragment_nearby.xml :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/listview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#+id/btn_New">
</ListView>
<Button
android:id="#+id/btn_New"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_marginBottom="20dp"
android:text="Button"
android:width="170dp"
android:layout_alignParentBottom="true" />
</RelativeLayout>
And the layout file of the item, item_place.xml :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name" />
<TextView
android:id="#+id/tvDesc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Desc" />
</LinearLayout>
Edit: Does anyone want to actually include a reason for the downvote? Especially when something like Custom Adapter for List View has 129 upvotes?
The issue is that ArrayAdapter does not know about List places:
Use this to fix it:
private static class NearbyAdapter extends ArrayAdapter<Place> {
public NearbyAdapter(Context context, List<Place> places) {
super(context, R.layout.item_place, places);
mContext = context;
placesList = places;
}
}
P/s: in this case, I think you need more control to set your place data to your view. Consider using BaseAdapter instead of ArrayAdapter.
Add following to your adapter:
#Override
public int getCount() {
return placesList.size();
}
After this you most likely encounter error with getItem so you will need to override that as well to return your object from the list.
You have to override getCount() method in ArrayAdapter to initialized listview like this:
#Override
public int getCount() {
return placesList.size();
}
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);
For my listview, I want to be able to display multiple textviews within it, with each textview displaying the items of a specific array associated with it. Right now is what I have:
public class GreatestHits extends ListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, Array1));
ListView lv = getListView();
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
String text = (String) ((TextView)view).getText();
}
});
}
static final String[] Array1 = new String[] {"Item1", "Item2"};
static final String[] Array2 = new String[] {"Item1", "Item2"};
static final String[] Array3 = new String[] {"Item1", "Item2"};
and the xml for R.layout.list_item:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="16sp"
android:id= "#+id/textView1"
>
</TextView>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="16sp"
android:id= "#+id/textView2"
>
</TextView>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="16sp"
android:id= "#+id/textView3"
>
</TextView>
How would I put array 2 and array 3 into the code so it can be displayed in the textviews of listview lv?
ArrayAdapter can only display data from one array in one textview. You will have to provide this functionality yourself by extending BaseAdapter yourself. I can't compile android code at the moment, so the following code is untested... but it should at least give you an indication of what you can do.
public class TripleArrayAdapter extends BaseAdapter {
private String[] array1, array2, array3;
private LayoutInflater inflater;
public TripleArrayAdapter(Context context, String[] a1, String[] a2, String[]a3) {
array1 = a1;
array2 = a2;
array3 = a3;
inflater =
(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return array1.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View currentView = convertView;
if(currentView==null) {
currentView = inflater.inflate(R.layout.list_item, parent, false);
}
TextView tView = (TextView)currentView.findViewById(R.id.textView1);
tView.setText(array1[position]);
tView = (TextView)currentView.findViewById(R.id.textView2);
tView.setText(array2[position]);
tView = (TextView)currentView.findViewById(R.id.textView3);
tView.setText(array3[position]);
return currentView;
}
}
Then, to use this adapter as your ListActivity's adapter, you would just say
setListAdapter(new TripleArrayAdapter(this, Array1, Array2, Array3));
I need help on how to change my code below to use my own XML list view. The items 'label', 'title', & 'discription' in my cursor needs to be inflated into itemLabel, itemTitle, & itemDiscription of the xml. Any help would be appreciated: I know how to do this from a simple array. The activity I created to get the data from a database works great - I just dont know how to use/display a custom lisView w/multilines. THNX!
REVISED: I managed to get the data to display from the database using my own custom XML file. The issue I have now is all three columns are returned in each TextView. ie: columns 'title', 'label', 'description' from the db all inflate into a single TextView as one continuous line. I cant figure out how to break it up into the correct TextViews; title = R.id.listTitle, label = R.id.label, and description should inflate into R.id.caption. Help!
The ListView Activity:(REVISED):
public class List_AC extends ListActivity {
private ArrayList<String> results = new ArrayList<String>();
File dbfile = new File("/mnt/sdcard/XXX/XXX/dB/XXX.db");
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbfile, null);
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
openAndQueryDatabase();
displayResultList();
}
private void displayResultList() {
AC_Adapter adapter = new AC_Adapter(getApplicationContext(),R.layout.list_item, results, results, results);
setListAdapter(adapter);
}
private void openAndQueryDatabase() {
try {
Cursor c = db.rawQuery("SELECT label, title, discription FROM AC_list", null);
if (c != null) {
if (c.moveToFirst()) {
do {
String i1 = c.getString(c.getColumnIndex("label"));
String i2 = c.getString(c.getColumnIndex("title"));
String i3 = c.getString(c.getColumnIndex("discription"));
results.add(i1 + i2 + i3);
} while (c.moveToNext());
}
}
} catch (SQLiteException se) {
Log.e(getClass().getSimpleName(),
"Could not create or Open the database");
} finally {
if (db != null)
db.close();
}
}
}
ADDED ADAPTER(AC_Adapter.java):
public class AC_Adapter extends ArrayAdapter<String> {
static List<String> Title = new ArrayList<String>();
static List<String> Label = new ArrayList<String>();
static List<String> Description = new ArrayList<String>();
Context myContext;
public AC_Adapter (Context context, int resource, List<String> aTitle, List<String> aLabel, List<String> aDescription){
super(context, resource, aTitle);
myContext = context;
Title= aTitle;
Label= aLabel;
Description = aDescription;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) myContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.list_item, null);
}
TextView tv_label = (TextView) v.findViewById(R.id.label);
TextView tv_title = (TextView) v.findViewById(R.id.listTitle);
TextView tv_decription = (TextView) v.findViewById(R.id.caption);
if (tv_label != null) {
tv_label.setText(Label.get(position));
}
if (tv_title != null) {
tv_title.setText(Title.get(position));
}
if (tv_decription != null) {
tv_decription.setText(Description.get(position));
}
return v;
}
}
This is the XML that needs to be created (list_view.xml) in the onCreate:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="30dip"
android:padding="4dip"
android:background="#drawable/gradient" >
<ImageButton
android:id="#+id/homeBtn"
android:src="#drawable/ic_menu_icon"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:background="#null" />
<TextView
android:id="#+id/titleBarTitle"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="18sp" />
<ImageButton
android:id="#+id/toolBtn"
android:src="#drawable/ic_menu_list"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:background="#null" />
</RelativeLayout>
<ListView
android:id="#+id/listItems"
android:layout_height="wrap_content"
android:layout_width="fill_parent" />
</LinearLayout>
and the list item (list_item.xml):
<?xml version="1.0" encoding="utf-8"?>
<TextView
android:id="#+id/itemLabel"
style="#style/listAcronym" />
<TextView
android:id="#+id/itemTitle"
style="#style/listTitle" />
<TextView
android:id="#+id/itemDiscription"
style="#style/listDiscription"/>
<ImageView
style="#style/listNextIcon" />
The basic process is to create a Custom Adapter which will contain the layout R.layout.list_item
Thus, you replace this line setListAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, results));
in your code
by
setListAdapter(new CustomAdapter(this,R.layout.list_item, results));
Now you need to create a CustomAdapter which extends ArrayAdapter or BaseAdapter and override the getView method to inflate R.layout.list_item
Please refer to this excellent tutorial by Mark Murphy
Custom ListView Adapter
If you do have any other doubts after trying this, please post it over here.
Everything is fine, just add a class extends from ArrayAdapter and do something like this:
public class CustomAdapter extends ArrayAdapter<String>
{
List<String> Title= new ArrayList<String>();
List<String> Label= new ArrayList<String>();
Context myContext;
public CustomAdapter (Context context, int resource,
int textviewresourceid,
List<String> aTitle,
List<String> aLabel)
{
super(context, resource,textviewresourceid,aType);
myContext = context;
Title= aTitle;
Label= aLabel;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
View v = convertView;
if (v == null)
{
LayoutInflater vi = (LayoutInflater)myContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.list_view, null);
}
TextView tv_title = (TextView) v.findViewById(R.id.id_tv_Title);
TextView tv_Label= (TextView) v.findViewById(R.id.id_tv_Label);
if(tv_title != null)
{
tv_title.setText(Title.get(position));
}
if(tv_Label != null)
{
tv_Label.setText(Label.get(position));
}
return v;
}
And then use this adapter like:
CustomAdapter adapter = new CustomAdapter(getAppContext(),R.layout.list_view,Textview Title Id,your lists...);
setListAdapter(adapter);
Something like this.... Hope it helps...
I have the correct anwser HERE along with the correct code.