custom android listview item not selectable on the whole area - android

I am using a ListView with a custom adapter for displaying items as pairs of title/subtitle TextViews.
Unfortunately, I can select an item just by clicking on its upper half, the one occupied by the title
Here is the code I am using:
journal_list.xml
<?xml version="1.0" encoding="utf-8"?>
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:drawSelectorOnTop="false"
android:background="#fff"
android:cacheColorHint="#fff"
android:paddingBottom="6dp"
/>
journal_list_item.xml for the list item's layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants"
>
<TextView
android:id="#+id/journal_entry_date"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textColor="#000"
android:textSize="18sp"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
/>
<TextView
android:id="#+id/journal_content"
android:paddingLeft="28dp"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textSize="16sp"
android:textColor="#555"
android:inputType="textMultiLine"
android:maxLines="2"
android:minLines="1"
android:layout_below="#id/journal_entry_date"
android:layout_alignParentLeft="true"
/>
Also the code for the adapter:
private class JournalAdapter extends ArrayAdapter<JournalEntry> {
Context ctxt;
public JournalAdapter(Context ctxt) {
super(ctxt, R.layout.journal_list_item);
this.ctxt = ctxt;
}
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
JournalHolder holder;
if (row == null) {
row = ((LayoutInflater)ctxt.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).
inflate(R.layout.journal_list_item, parent, false);
holder = new JournalHolder(row);
row.setTag(holder);
} else {
holder = (JournalHolder) row.getTag();
}
JournalEntry crt = getItem(position);
holder.getDate().setText(crt.dateWritten);
holder.getContent().setText(crt.content);
return row;
}
}
private static class JournalHolder {
private TextView date;
private TextView content;
private View base;
public JournalHolder(View base) {
this.base = base;
}
public TextView getDate() {
if (date == null)
date = (TextView) base.findViewById(R.id.journal_entry_date);
return date;
}
public TextView getContent() {
if (content == null)
content = (TextView) base.findViewById(R.id.journal_content);
return content;
}
}
Code from the ListActivity's onCreate() method:
private JournalAdapter adapter;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.journal_list);
adapter = new JournalAdapter(this);
setListAdapter(adapter);
registerForContextMenu(getListView());
}
Also, I am calling a method called updateList() in onResume()
private void updateList() {
adapter.clear();
Cursor cursor = helper.listJournal(start, end);
cursor.moveToFirst();
JournalEntry crt;
while (!cursor.isAfterLast()) {
crt = new JournalEntry();
crt.dateWritten = cursor.getString(cursor.getColumnIndex("date_written"));
crt.content = cursor.getString(cursor.getColumnIndex("content"));
crt.id = cursor.getInt(cursor.getColumnIndex("entry_id"));
adapter.add(crt);
cursor.moveToNext();
}
cursor.close();
adapter.notifyDataSetChanged();
}
List item clicking is handled in the onListItemClick of my ListActivity, as follows:
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Intent intent = new Intent(this, JournalEditor.class);
intent.setAction(Intent.ACTION_EDIT);
intent.putExtra("entry_id", adapter.getItem(position).id);
startActivity(intent);
}
Apparently, I am forgetting something important, and that's why this whole weird thing happens.
I have found a similar discussion here: http://groups.google.com/group/android-developers/browse_thread/thread/5636c8ea74033657 but it wasn't very helpful.

The problem may be from the clicking of the textviews. When you set the views of the listview items as clickable, they override the click of the listview item and the click will only work when the specific view of the item is clicked.
If this is the case, do the following for your two textviews in the getView() function:
TextView tv;
tv.setFocusable(false);
tv.setClickable(false);
Then set the listview to clickable: listView1.setClickable(true);

Related

Moving list view elements to another list view in a separate activity

I'm having trouble understanding how to use Intent to move list view elements. So I've made a separate project to practice this before actually figuring it out in my app. Basically, I want to have a "Favorites" activity that can be populated from something like a search results page. Instead of a search results page, I've just created a list view with some sample elements in them with a favorites button in each. I just need some guidance on how to go from there. Here is my code so far
MainActivity.java
public class MainActivity extends Activity {
private ArrayList<String> data = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView) findViewById(R.id.listView);
generateList();
listView.setAdapter(new MyListAdapter(this, R.layout.item_view, data));
}
private void generateList() {
for (int i = 0; i < 5; i++) {
data.add("row/item " + i);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private class MyListAdapter extends ArrayAdapter<String> {
private int layout;
public MyListAdapter(Context context, int resource, List<String>
objects) {
super(context, resource, objects);
layout = resource;
}
#Override
public View getView(final int position, View convertView, ViewGroup
parent) {
ViewHolder minViewHolder = null;
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(layout, parent, false);
ViewHolder viewHolder = new ViewHolder();
viewHolder.title = (TextView)
convertView.findViewById(R.id.list_item_text);
viewHolder.button = (Button)
convertView.findViewById(R.id.favorites_button);
viewHolder.button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v) {
Toast.makeText(getContext(), "sent item " + position + "
to favorites tab", Toast.LENGTH_SHORT).show();
// data.remove(position);
MyListAdapter.this.notifyDataSetChanged();
}
});
convertView.setTag(viewHolder);
} else {
minViewHolder = (ViewHolder) convertView.getTag();
minViewHolder.title.setText(getItem(position));
}
return convertView;
}
}
public class ViewHolder{
TextView title;
Button button;
}
}
activity_main.xml
<RelativeLayout 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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MainActivity">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/listView"
android:layout_centerHorizontal="true" /> </RelativeLayout>
item_view.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:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:id="#+id/list_item_text"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true" />
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="fav"
android:id="#+id/favorites_button"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true" />
</RelativeLayout>
I haven't set up a second activity because I wanted ideas on how to create a list that is empty but can be populated by that favorites button press. Any help at all is greatly appreciated!
Update arraylist according to favourite and call
adapter.notifyDataChanged();
if listview is same,
otherwise for different listview call another listview with adapter and new filtered arraylist

Android custom ListView layout problems

Hi guys, I tried to learn how to use custom ListView by this page
It works fine but I have problems with another options.
Cannot set margin to listItems
Cannot set backgro
Cannot set OnItemClickListener
1# Margin
First of all I'm trying to set margin between list items but nothing works. I try to set margin on RelativeLayout in rowlayout.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="75dp"
android:background="#drawable/rounded"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
>
2# Background
I want to set background on whole screen under listView. I think I put black color on every View in every xml I found but nothing affect the background. I can change background of single list items, that's all.
android:background="#000000"
3#OnItemClickListener
My last problem is that I'm not able to set onItemClickListener. I have no idea how to set it if I don't have simply ListView but RelativeLayout with TextView etc.
I guess I have to use
setOnClickListener(new OnClickListener()
and after that
public void onClick(View arg0) {
but I have no idea on which View I have to use this method.
Files
MyAdapter.java
public class MyAdapter extends ArrayAdapter<Model> {
private final Context context;
private final ArrayList<Model> modelsArrayList;
public MyAdapter(Context context, ArrayList<Model> modelsArrayList) {
super(context, R.layout.rowlayout, modelsArrayList);
this.context = context;
this.modelsArrayList = modelsArrayList;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// 1. Create inflater
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// 2. Get rowView from inflater
View rowView = null;
if(!modelsArrayList.get(position).isGroupHeader()){
rowView = inflater.inflate(R.layout.rowlayout, parent, false);
// 3. Get icon,title & counter views from the rowView
ImageView imgView = (ImageView) rowView.findViewById(R.id.item_icon);
TextView titleView = (TextView) rowView.findViewById(R.id.item_title);
TextView counterView = (TextView) rowView.findViewById(R.id.item_counter);
// 4. Set the text for textView
imgView.setImageResource(modelsArrayList.get(position).getIcon());
titleView.setText(modelsArrayList.get(position).getTitle());
counterView.setText(modelsArrayList.get(position).getCounter());
}
else{
//rowView = inflater.inflate(R.layout.group_header, parent, false);
// TextView titleView = (TextView) rowView.findViewById(R.id.header);
// titleView.setText(modelsArrayList.get(position).getTitle());
}
// 5. retrn rowView
return rowView;
}
}
Model.java
package com.example.sunny.katan;
/**
* Created by Sunny on 15.09.14.
*/
public class Model{
private int icon;
private String title;
private String counter;
private boolean isGroupHeader = false;
public Model(String title) {
this(-1,title,null);
isGroupHeader = true;
}
public Model(int icon, String title, String counter) {
super();
this.icon = icon;
this.title = title;
this.counter = counter;
}
public String getCounter() {
return counter;
}
public String getTitle() {
return title;
}
public int getIcon() {
return icon;
}
public boolean isGroupHeader() {
return false;
}
public void setGroupHeader(boolean isGroupHeader) {
this.isGroupHeader = isGroupHeader;
}
//gettters & setters...
}
main.java
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
// if extending Activity
//setContentView(R.layout.activity_main);
// 1. pass context and data to the custom adapter
MyAdapter adapter = new MyAdapter(this, generateData());
// if extending Activity 2. Get ListView from activity_main.xml
//ListView listView = (ListView) findViewById(R.id.listview);
// 3. setListAdapter
//listView.setAdapter(adapter); if extending Activity
setListAdapter(adapter);
}
private ArrayList<Model> generateData(){
ArrayList<Model> models = new ArrayList<Model>();
models.add(new Model(R.raw.barbell,"Cviky","37"));
models.add(new Model(R.raw.stretching,"Protahování","94"));
models.add(new Model(R.raw.work,"Generování workoutu","293"));
return models;
}
rowlayout.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="75dp"
android:background="#drawable/rounded"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
>
<!-- icon -->
<ImageView
android:id="#+id/item_icon"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_alignParentLeft="true"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_centerVertical="true"
android:src="#raw/barbell"
/>
<!-- title -->
<TextView
android:id="#+id/item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_toRightOf="#+id/item_icon"
android:layout_marginTop="30dp"
android:layout_alignBaseline="#+id/item_counter"
android:textSize="20dp"
/>
<!-- counter -->
<TextView
android:id="#+id/item_counter"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_alignParentRight="true"
android:layout_marginRight="8dp"
android:layout_centerVertical="true"
android:background="#drawable/rectangle"
android:gravity="center"
android:textColor="#FFFFFF"
android:textSize="12sp"
android:textStyle="bold" />
</RelativeLayout>
main.xml
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="false"
>
<LinearLayout
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".katan_lobby"
android:orientation="vertical"
>
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/menu"
android:layout_gravity="center_horizontal"
android:background="#238CD4"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/prvniItemSeznamu"
android:background="#238CD4"
style="#style/listView"
/>
</LinearLayout>
</ScrollView>
Looks like you are half way there in your activity.
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
MyAdapter adapter = new MyAdapter(this, generateData());
ListView listView = (ListView) findViewById(R.id.menu);
listView.setAdapter(adapter); if extending Activity
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
onItemClick(AdapterView<?> parent, View view, int position, long id)
{
//You now have the position but you will need to get your model list and use .get(position) and cast it to Model to get access to it.
}
});
}
//First define your list view item xml… something like this.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#color/white"
android:layout_marginTop="10dp"
android:padding="10dp" >
<TextView
android:id="#+id/item1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/custom_blue"
android:text="TextView" />
<TextView
android:id="#+id/item2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textColor="#color/custom_grey"
android:text="TextView" />
</LinearLayout>
//Then you define your list list adapter.
public class MyListAdapter extends ArrayAdapter<MyModel> {
private Context context;
private ArrayList<MyModel> myModel;
public MyListAdapter(Context context, ArrayList<MyModel> myModelList) {
super(context, R.id.icon, myModelList);
this.context = context;
this.myModelList = myModelList;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = null;
View rowView = convertView;
TextView myItemName = (TextView)rowView.findViewById(R.id.item1);
TextView myItemTitle = (TextView)rowView.findViewById(R.id.item2);
//use your models getters/setters
myItemName.setText(myModelList.get(position).getItemTitle());
myItemTitle.setText(myModelList.get(position).getItemName());
return rowView
}
}
//Now use both the list adapter and list item in your ListFragment or ListActivity.
ArrayList<MyModel> myModelList = new ArrayList<MyModel>();
MyListAdapter myApt = new MyListAdapter(this, myModelList);
setListAdapter(myApt);
//For clicking on the items:
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// ListView Clicked item value
String itemValue = l.getItemAtPosition(position).toString();
doSomethingWihtMyItemMethod(position);
}
/* You can customize your list item anyway you like, just be aware of screen real estate when doing so.Hope this helps. */

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: Custom SimpleCursorAdapter does not load all data

In need of assistance, I have a listview activity which I want to display couple of textfields per item plus 2 buttons (like contacts app having a call button and a text message button. Reading tutorials I found out how to get the buttons to be clickable, but now my textviews (all except 1) don't display any data other then the stock text I've left in the layout file. The 1 text view does display the data I require it to. No where in my custom SCA do I feed it specific data so I'm assuming it happens in the background.
My R.id.company_address_details_phone loads the needed data without any manipulation on my part, but non of the other TextViews in my ViewHolder display any data. My For loop attached to my call button does output data from my cursor so I know it's not that I'm missing data. Any and all help is appreciated.
As a side note, when first wrote the code and did not use a custom SimpleCursorAdapter all my text views populated as expected (i just couldnt click buttons). This leads me to assume that my CompanyActivity class has no errors but that I'm missing something in my CompanyDetailsCursroAdapter class.
*EDIT***
So I'm answering my own question after I looked back and tried something. non of my views where being populated, I just had one of my views set with default text that made it appear as if it was pulled from my DB. I'm now populating my views with data from the cursor adapter passed to my custom cursor adapter using the below code. I would like to know if this is the best way of doing it or is there a more streamlined or android approved method.
viewHolder.addressTextView.setText(companyDetailsCursor.getString(companyDetailsCursor.getColumnIndex("AddressStreet")));
viewHolder.cityTextView.setText(companyDetailsCursor.getString(companyDetailsCursor.getColumnIndex("AddressCity")));
viewHolder.stateTextView.setText(companyDetailsCursor.getString(companyDetailsCursor.getColumnIndex("AddressState")));
viewHolder.zipTextView.setText(companyDetailsCursor.getString(companyDetailsCursor.getColumnIndex("AddressZip")));
viewHolder.phoneTextView.setText(companyDetailsCursor.getString(companyDetailsCursor.getColumnIndex("AddressPhone")));
CompanyDetailsCursorAdapter.java
public class CompanyDetailsCursorAdapter extends SimpleCursorAdapter implements Filterable{
private final Context context;
private int layout;
Cursor companyDetailsCursor;
public CompanyDetailsCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
super(context, layout, c, from, to);
this.context = context;
this.layout = layout;
this.companyDetailsCursor = c;
}
static class ViewHolder {
protected TextView addressTextView;
protected TextView cityTextView;
protected TextView stateTextView;
protected TextView zipTextView;
protected TextView phoneTextView;
protected ImageButton callButton;
protected ImageButton mapButton;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
final LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.company_address_details, null);
convertView.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
viewHolder = new ViewHolder();
viewHolder.addressTextView = (TextView) convertView.findViewById(R.id.company_address_details_street);
viewHolder.cityTextView = (TextView) convertView.findViewById(R.id.company_address_details_city);
viewHolder.stateTextView = (TextView) convertView.findViewById(R.id.company_address_details_state);
viewHolder.zipTextView = (TextView) convertView.findViewById(R.id.company_address_details_zip);
viewHolder.phoneTextView = (TextView) convertView.findViewById(R.id.company_address_details_phone);
viewHolder.callButton = (ImageButton) convertView.findViewById(R.id.company_address_details_call_button);
viewHolder.callButton.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
companyDetailsCursor.moveToPosition(position);
if (RouteTrackerGlobal.APP_DEBUG) { Log.d(RouteTrackerGlobal.APP_TAG,"getview position set to " + String.valueOf(position));}
for (int i = 0; i < companyDetailsCursor.getColumnCount();i++){
Log.i(RouteTrackerGlobal.APP_TAG, companyDetailsCursor.getString(i));
}
}
});
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
return convertView;
}
CompanyActivity.java
public class CompanyActivity extends ListActivity {
DbAdapter dbAdapter;
int companyID;
Context context = this;
Cursor companyDetailsCursor;
#Override
public void onCreate(Bundle savedInstanceBundle) {
super.onCreate(savedInstanceBundle);
dbAdapter = new DbAdapter(this);
setContentView(R.layout.company_activity);
Bundle companyActivityBundle = getIntent().getExtras();
companyID = companyActivityBundle.getInt("CompanyID");
ListView list = getListView();
list.setOnItemLongClickListener(new OnItemLongClickListener(){
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
// TODO Auto-generated method stub
return false;
}
});
}
#Override
public void onPause() {
dbAdapter.close();
super.onPause();
}
#Override
public void onResume() {
dbAdapter.open();
super.onResume();
loadDetails();
}
#Override
protected void onListItemClick (ListView l, View v, int position, long id){
//TODO: When item in list clicked, call activity to display address and directions
}
public void loadDetails() {
TextView companyLabel = (TextView) findViewById(R.id.company_activity_company_label);
companyDetailsCursor = dbAdapter.getCompanyDetails(companyID);
startManagingCursor(companyDetailsCursor);
companyDetailsCursor.moveToFirst();
companyLabel.setText(companyDetailsCursor.getString(companyDetailsCursor.getColumnIndex("CompanyName")));
String[] columns = new String[] {"AddressPhone", "AddressStreet", "AddressCity", "AddressState", "AddressZip"};
int[] to = new int[] {R.id.company_address_details_phone, R.id.company_address_details_street, R.id.company_address_details_city, R.id.company_address_details_state, R.id.company_address_details_zip};
CompanyDetailsCursorAdapter companyDetailsAdapter = new CompanyDetailsCursorAdapter(context, R.layout.company_address_details, companyDetailsCursor, columns, to);
setListAdapter(companyDetailsAdapter);
}
}
Company_Address_Details.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<RelativeLayout android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/company_address_details_phone"
style="#style/company_address_listview"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:text="#string/company_address_details_phone_default" />
<ImageButton android:id="#+id/company_address_details_call_button"
style="#style/company_address_listview"
android:layout_alignParentRight="true"
android:layout_centerInParent="true"
android:background="#android:color/transparent"
android:src="#android:drawable/sym_action_call"
android:contentDescription="#string/company_address_details_phone_hint"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="#+id/company_address_details_call_button1"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/company_address_details_street"
style="#style/company_address_listview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/company_address_details_street_default" />
</LinearLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/company_address_details_city"
style="#style/company_address_listview"
android:layout_width="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:text="#string/company_address_details_city_default" />
<TextView
android:id="#+id/company_address_details_state"
style="#style/company_address_listview"
android:layout_centerInParent="true"
android:layout_centerVertical="true"
android:text="#string/company_address_details_state_default" />
<TextView
android:id="#+id/company_address_details_zip"
style="#style/company_address_listview"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:text="#string/company_address_details_zip_default" />
</RelativeLayout>
</LinearLayout>
<ImageButton
android:id="#+id/company_address_details_call_button1"
style="#style/company_address_listview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerHorizontal="false"
android:layout_centerInParent="false"
android:layout_centerVertical="true"
android:background="#android:color/transparent"
android:contentDescription="#string/company_address_details_phone_hint"
android:paddingLeft="20dp"
android:src="#android:drawable/ic_dialog_map" />
</RelativeLayout>
</LinearLayout>

Use array adapter with more views in row in listview

I have stumbled upon a problem I can't quite get my head around, so I was hoping perhaps someone here have had the same problem or knew a good way of solving the problem.
I have created a view containing a ListView. This ListView contains two TextView.
The problem is that I don't know where I send the values which are meant to go in the second text view using the ArrayAdapter. Is there a way to send with more information to the ArrayAdapter so that I can feed the "todaysmenu" TextView?
The ArrayAdapter method:
private void createList() {
ListView lv = (ListView) findViewById(R.id.mylist);
String[] values = new String[] { "Android", "Linux", "OSX",
"WebOS", "Windows7", "Ubuntu", "OS/2"
};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.rowlayout, R.id.restaurantname, values);
lv.setAdapter(adapter);
}
The row markup:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/restaurantname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#+id/restaurantname"
android:textSize="23dp" >
</TextView>
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#+id/todaysmenu" />
</LinearLayout>
The activity layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/mylist"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
</LinearLayout>
At the beginning I got everything to work, but when I added the second textfield problems arouse. In advance, thank you for your help!
To achieve this you have to build a custom adapter and inflate your custom row layout. Using ArrayAdapter won't work because
By default this class expects that the provided resource id references
a single TextView. If you want to use a more complex layout, use the constructors that also takes a field id. That field id should reference a TextView in the larger layout resource.
So, your custom adapter class could be somthing like:
public class CustomAdapter extends ArrayAdapter {
private final Activity activity;
private final List list;
public CustomAdapter(Activity activity, ArrayList<Restaurants> list) {
this.activity = activity;
this.list = list;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
ViewHolder view;
if(rowView == null)
{
// Get a new instance of the row layout view
LayoutInflater inflater = activity.getLayoutInflater();
rowView = inflater.inflate(R.layout.rowlayout, null);
// Hold the view objects in an object, that way the don't need to be "re- finded"
view = new ViewHolder();
view.retaurant_name= (TextView) rowView.findViewById(R.id.restaurantname);
view.restaurant_address= (TextView) rowView.findViewById(R.id.textView1);
rowView.setTag(view);
} else {
view = (ViewHolder) rowView.getTag();
}
/** Set data to your Views. */
Restaurants item = list.get(position);
view.retaurant_name.setText(item.getTickerSymbol());
view.restaurant_address.setText(item.getQuote().toString());
return rowView;
}
protected static class ViewHolder{
protected TextView retaurant_name;
protected TextView restaurant_address;
}
}
And your Restaurant.java class could as simple as I describe below:
public class Restaurants {
private String name;
private String address;
public Restaurants(String name, String address) {
this.name = name;
this.address = address;
}
public void setName(String name) {
this.name= name;
}
public String getName() {
return name;
}
public void setAddress(String address) {
this.address= address;
}
public String getAddress() {
return address;
}
}
Now, in you main activity just bind you list with some data, like;
/** Declare and initialize list of Restaurants. */
ArrayList<Restaurants> list = new ArrayList<Restaurants>();
/** Add some restaurants to the list. */
list.add(new Restaurant("name1", "address1"));
list.add(new Restaurant("name2", "address2"));
list.add(new Restaurant("name3", "address3"));
list.add(new Restaurant("name4", "address4"));
list.add(new Restaurant("name5", "address5"));
list.add(new Restaurant("name6", "address6"));
At this point you're able to set the custom adapter to your list
ListView lv = (ListView) findViewById(R.id.mylist);
CustomAdapter adapter = new CustomAdapter(YourMainActivityName.this, list);
lv.setAdapter(adapter);
This is all and it should work nicelly, but I strongly recommend you to google for some better alternatives to implement others Adapters.
You could try this https://devtut.wordpress.com/2011/06/09/custom-arrayadapter-for-a-listview-android/. You have to create a custom class Item with fields you need and extend ArrayAdapter .
I think that your problem is here:
Instead of this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/restaurantname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#+id/restaurantname"
android:textSize="23dp" >
</TextView>
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#+id/todaysmenu" />
</LinearLayout>
Try something like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/restaurantname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="test text"
android:textSize="23dp" >
</TextView>
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="test text" />
</LinearLayout>
If that works, then place your text in the /res/val/string folder like so:
<string name="testText">Put your text here...</string>
and then call like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/restaurantname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/testText"
android:textSize="23dp" >
</TextView>
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/testText" />
</LinearLayout>
You would then set the dynamic values like this:
TextView tv = (TextView)findViewById(R.id.restaurantname);
tv.setText(values);
I had to solve the same problem and tried to use the arrayadapter as answered here above, but it didn't work.
Later I succeeded to do it with baseadapter -- this is the adapter:
public class BusinessAdapter2 extends BaseAdapter {
private final ArrayList<Business> myList;
LayoutInflater inflater;
Context context;
public BusinessAdapter2(Context context, ArrayList<Business> myList) {
this.myList = myList;
this.context = context;
inflater = LayoutInflater.from(this.context);
}
#Override
public int getCount() {
return myList.size();
}
#Override
public Object getItem(int position) {
return myList.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView==null) convertView = inflater.inflate(R.layout.business_list_item_2, parent, false);
// assign the view we are converting to a local variable
View v = convertView;
Business b = myList.get(position);
if (b != null) {
TextView name = (TextView) v.findViewById(R.id.textview_name);
TextView address = (TextView) v.findViewById(R.id.textview_address);
TextView description = (TextView) v.findViewById(R.id.textview_description);
TextView discount = (TextView) v.findViewById(R.id.textview_discount);
// check to see if each individual textview is null.
// if not, assign some text!
if (name != null){
name.setText(b.name);
}
if (address != null){
address.setText(b.address);
}
if (description != null){
description.setText(b.description);
}
if (discount != null){
discount.setText(b.discountRate);
}
}
// the view must be returned to our activity
return v;
}
}
this is the Object class I used (Business):
public class Business {
String name,address,description,discountRate;
public Business(){}
public Business(String name,String address,String description,String discountRate){
this.name=name;
this.address=address;
this.description=description;
this.discountRate=discountRate;
}
}
and this is how I populate the listview into the adapter:
ArrayList<Business> businesses2=new ArrayList<Business>(Arrays.asList(for_listview_objects));
adapter_objects =new BusinessAdapter2(
context, // The current context (this activity)
businesses2);
listView.setAdapter(adapter_objects);

Categories

Resources