So I'm relatively new to android programming, and currently working on a custom listView. What I'm trying to achieve is the following:
Retrieve a list of articles from a database.
Get all unique values from the 'category' column to create a list of
categories.
Populate a listView with these categories
Add a listener for each category click which takes the user to the
first article in that category.
I've managed to do all of the above, but now want to take it further. I have a status column in the database, where the value is either 'read' or 'unread'. What I want to do is the following:
If all articles in a category are 'read', to grey-out that category
in the listview, and to ignore clicks on that particular item.
I have absolutely no idea how to format individual items within a listview...any suggestions? My code is as follows:
start.java:
public class Start extends Activity {
private ListView mainListView ;
private ArrayAdapter<String> listAdapter ;
public static final String MYDATABASE_NAME = "questions.db";
public static final String MYDATABASE_TABLE = "questions";
public static final int MYDATABASE_VERSION = 1;
public static final String KEY_ID = "_id";
public static final String KEY_CONTENT = "category";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.start);
// Query database
SQLiteDatabase db;
db = openOrCreateDatabase(
"questions.db"
, SQLiteDatabase.CREATE_IF_NECESSARY
, null
);
db.setVersion(1);
db.setLocale(Locale.getDefault());
db.setLockingEnabled(true);
ArrayList<String> categoryList = new ArrayList<String>();
Cursor cur = db.query("questions", null, null, null, null, null, null);
cur.moveToFirst();
while (cur.isAfterLast() == false) {
if (categoryList.contains(cur.getString(11))) {
// do nothing
} else {
// add to list
categoryList.add(cur.getString(11));
}
cur.moveToNext();
}
cur.close();
Collections.sort(categoryList);
categoryList.add(0, "All");
// Find the ListView resource.
mainListView = (ListView) findViewById( R.id.mainListView );
// Create ArrayAdapter using the category list.
listAdapter = new ArrayAdapter<String>(this, R.layout.simplerow, categoryList);
// Set the ArrayAdapter as the ListView's adapter.
mainListView.setAdapter( listAdapter );
mainListView.setTextFilterEnabled(true);
mainListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {
String clickedCat = (String) mainListView.getItemAtPosition(position);
finish();
Intent myIntent = new Intent(getApplicationContext(), NextClass.class);
myIntent.putExtra("passedCategory", clickedCat);
myIntent.putExtra("startTrigger", "go");
startActivity(myIntent);
}
});
}
}
start.xml
<?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"
android:background="#android:color/black">
<TextView
android:text="#string/categories"
android:layout_width="fill_parent"
android:layout_height="#dimen/topbar_container"
android:background="#drawable/topgradient"
android:gravity="center_vertical|center_horizontal"
android:textColor="#color/primarytext"
android:textSize="#dimen/topbar_font"
android:textStyle="bold"
android:shadowColor="#000000"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="2"></TextView>
<ListView android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/mainListView"></ListView>
</LinearLayout>
simplerow.xml
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rowTextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:textSize="16sp" android:textStyle="bold">
</TextView>
You need to set up a ViewBinder, then call listAdapter.setViewBinder.
You need to create a custom adapter for this:
CustomAdapter.class:
public class CustomAdapter extends SimpleCursorAdapter{
Cursor dataCursor;
LayoutInflater mInflater;
Context context;
ArrayList<String[]> arrayList;
public static HashMap<Integer,String> myList=new HashMap<Integer,String>();
public CustomAdapter(Context context, int layout, Cursor dataCursor, String[] from,
int[] to) {
super(context, layout, dataCursor, from, to);
this.context=context;
this.dataCursor = dataCursor;
mInflater = LayoutInflater.from(context);
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if(convertView==null)
{
convertView = mInflater.inflate(R.layout.custom_listitem, null);
holder = new ViewHolder();
holder.textview=(TextView)convertView.findViewById(R.id.textview);
holder.layout=(LinearLayout)findViewById(R.id.layout);
convertView.setTag(holder);
}
else
{
holder=(ViewHolder)convertView.getTag();
}
dataCursor.moveToPosition(position);
String id=Integer.toString(dataCursor.getInt(dataCursor.getColumnIndexOrThrow("_id")));
myList.put(position, id);
holder.textview.setText(dataCursor.getString(11));
if(dataCursor.getString(dataCursor.getColumnIndex("index")).equals("read"))
{
holder.layout.setBackgroundColor(Color.GRAY);
}
// other code according to the functionality you want
return convertView;
}
static class ViewHolder
{
TextView textview;
LinearLayout layout;
}
}
custom_listitem.xml:
<?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"
android:background="#FFFFFF"
android:id="#+id/layout"
android:padding="5dip"
>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="17dip"
android:gravity="left"
android:padding="5dip"
android:id="#+id/textview"
/>
</LinearLayout>
Now,use it in activity like:
MainActivity.class:
...
mainListView = (ListView) findViewById( R.id.mainListView );
Cursor cursor = db.query("questions", null, null, null, null, null, null);
CustomAdapter ca=new CustomsAdapter(context,R.layout.custom_listitem,cursor,new String[]{"id","index"},new int[]{R.id.textview,R.id.textview});
mainListView.setAdapter(ca);
mainListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View view, int position,
long id) {
String id=CustomAdapter.myList.get(position);
Cursor findIndex=db.query("questions", null, "_id="+id, null, null, null, null);
findIndex.moveToFirst();
if(findIndex.getString(findIndex.getColumnIndex("index").equals("unread"))
{
// do something for "unread" categories
}
}
});
...
I don't know the way,you can disable click on a particular listitem but yes,you can do the stuff under certain condition to let user feel like some of the items are unclickable.
Related
Actually I can do a loop and log in console all rows of my table:
db.getAllPoids();
List<Poids> poids = db.getAllPoids();
for (Poids val : poids) {
String log = "Id: " + val.getId() + " ,Date: " + val.getDate_enr() + " ,Poids: " + val.getPoids() + " ,Evolution: " + val.getEvolution() ;
// Writing Contacts to log
Log.d("Name: ", log);
}
DatabaseHandler:
public List<Poids> getAllPoids() {
List<Poids> poidsList = new ArrayList<Poids>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_POIDS;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Poids poid = new Poids();
poid.setId(Integer.parseInt(cursor.getString(0)));
poid.setPoids(Integer.parseInt(cursor.getString(1)));
poid.setDate_enr(cursor.getString(2));
poid.setEvolution(cursor.getString(3));
poid.setId_utilisateurs(Integer.parseInt(cursor.getString(4)));
// Adding contact to list
poidsList.add(poid);
} while (cursor.moveToNext());
}
But now Iwan't to do a better view, I need something like a table or liste, I know that they're listview exemple on google, but not with this method that I use.
And in my view I need to have3 rows:
get the date in the first, the row "poids" in the second and n image view containing the id to delete the row on click. It is possible ? I don't know how to do.
PoidsAdapter:
public class PoidsAdapter extends ArrayAdapter<Poids> {
private Context mContext;
private List<Poids> mListPoids;
public PoidsAdapter(Context context, int resource, List<Poids> objects) {
super(context, resource, objects);
this.mContext = context;
this.mListPoids = objects;
}
#Override
public int getCount() {
return mListPoids.size();
}
#Override
public Poids getItem(int position) {
return mListPoids.get(position);
}
#Override
public View getView(final int position, View view, final ViewGroup parent) {
final holder holder;
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.listpoids, null);
holder = new holder();
holder.mTvTitle = (TextView) view.findViewById(R.id.textViewDate);
holder.mTvMediaName = (TextView) view.findViewById(R.id.textViewPoids);
holder.mImageUrl = (Button) view.findViewById(R.id.buttonSupprimer);
return view;
}
public class holder {
public Button mImageUrl;
public TextView mTvTitle;
public TextView mTvMediaName;
}
}
UPDATE 2:
I put a text view hidden to keep the id:
#Override
public View getView(final int position, View view, final ViewGroup parent) {
final ViewHolder holder;
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.listpoids, null);
holder = new ViewHolder();
holder.mTvTitle = (TextView) view.findViewById(R.id.textViewDate);
holder.mTvMediaName = (TextView) view.findViewById(R.id.textViewPoids);
holder.poidsId = (TextView) view.findViewById(R.id.textViewPoidsId);
holder.mImageUrl = (Button) view.findViewById(R.id.buttonSupprimer);
Poids poids = mListPoids.get(position);
holder.mTvTitle.setText(poids.getDate_enr().toString());
holder.mTvMediaName.setText(String.valueOf(poids.getPoids()).toString() + "kg");
holder.poidsId.setText(String.valueOf(poids.getId()).toString());
return view;
}
Fragment:
public class MonPoidsFragment extends Fragment {
DatabaseHandler db = new DatabaseHandler(getActivity());
public MonPoidsFragment(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//View rootView = inflater.inflate(R.layout.accueil_activity, container, false);
View view = inflater.inflate(R.layout.monpoids_activity, container, false);
final ListView listView=(ListView) view.findViewById(R.id.listView);
Button buttonAjouter = (Button)view.findViewById(R.id.buttonAjouter);
Button buttonSupprimer = (Button)view.findViewById(R.id.buttonSupprimer);
db = new DatabaseHandler(getActivity());
db.getAllPoids();
final List<Poids> poids = db.getAllPoids();
PoidsAdapter mAdapter = new PoidsAdapter(getActivity(), R.layout.listpoids, poids);
listView.setAdapter(mAdapter);
Log.d("getCount(): ", "" + mAdapter.getCount());
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(final AdapterView<?> parent, View view, final int position, long id) {
poids.remove(position);
db.deletePoids(position);
}
});
buttonSupprimer.setOnClickListener(
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
poids.remove(position);
db.deletePoids(position);
}
})});
buttonAjouter.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
Fragment fragment = null;
fragment = new AjoutPoidsFragment();
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.frame_container, fragment).commit();
}
});
return view;
}
}
Database:
public void deletePoids(int rowID) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_POIDS, KEY_ID + " =? ", new String[]{String.valueOf(rowID)});
}
monpoids_activity:
<?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="fill_parent"
android:focusable="true"
android:focusableInTouchMode="true"
android:descendantFocusability="beforeDescendants"
android:background="#ffffff"
android:orientation="vertical">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:padding="10dp">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Ajouter un poids"
android:id="#+id/buttonAjouter"
android:background="#70cbed"
android:textColor="#ffffff"
android:textAlignment="center"
android:layout_marginTop="20dp" />
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/listView" />
</LinearLayout>
</RelativeLayout>
listpoids.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"
android:background="#bbd3dc">
<TextView
android:id="#+id/textViewDate"
android:layout_gravity="center"
android:layout_width="0.7in"
android:layout_height="wrap_content"
android:text="TextView"
android:padding="10dp" />
<TextView
android:layout_gravity="center"
android:layout_width="0.7in"
android:layout_height="wrap_content"
android:text="New Text"
android:id="#+id/textViewPoids"
android:padding="10dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textViewPoidsId"
android:text="hidden"
android:visibility="gone"/>
<Button
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Supprimer"
android:id="#+id/buttonSupprimer" />
</LinearLayout>
add method to DatabaseHandler
public static void delete(int rowID) {
SQLiteDatabase database = this.getWritableDatabase();
database.delete(TABLE_POIDS, COL_ID + " =? ", new String[]{String.valueOf(rowID)});
}
in listview.setOnItemClickListener
#Override
public void onItemClick(final AdapterView<?> parent, View view, final int position, long id) {
Poids poids= mAdapter.getItem(position);
int id = poids.getId();
poids.remove(position);
db.delete(id);
mAdapter.notifyDataSetChanged();
}
Create PoidsAdapter.class
public class PoidsAdapter extends ArrayAdapter<Poids> {
private Context mContext;
private List<Poids> mListPoids;
public PoidsAdapter(Context context, int resource, List<Poids> objects) {
super(context, resource, objects);
this.mContext = context;
this.mListPoids = objects;
}
#Override
public int getCount() {
return mListPoids.size();
}
#Override
public Poids getItem(int position) {
return mListPoids.get(position);
}
#Override
public View getView(final int position, View view, final ViewGroup parent) {
final ViewHolder holder;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.item_poids, null);
holder = new ViewHolder();
holder.mTvTitle = (TextView) view.findViewById(R.id.text_title);
holder.mTvMediaName = (TextView) view.findViewById(R.id.text_mediaName);
holder.mImageUrl = (ImageView) view.findViewById(R.id.image_url);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
final Poids poids = mListPoids.get(position);
holder.mTvTitle.setText(poids.getTitle());
holder.mTvMediaName.setText(poids.getMediaName());
Picasso.with(mContext).load(poids.getImageUrl())
//.fit().centerInside()
.into(holder.mImageUrl);
return view;
}
public class ViewHolder {
public ImageView mImageUrl;
public TextView mTvTitle;
public TextView mTvMediaName;
}
}
in Oncreate
List<Poids> poids= db.getAllPoids();
PoidsAdapter mAdapter = new PoidsAdapter(this, R.layout.item_poids, poids);
listView.setAdapter(mAdapter);
Add picasso to build.gradle
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.1'
compile 'com.squareup.picasso:picasso:2.5.2'
}
in activity_main.xml add control ListView
create layout item_poids.xml have 3 control TextView, TextView, ImageView
Yes it is possible.
One way is to use a ListView.
This requires the ListView to be defined as part of the layout e.g. :-
<ListView
android:id="#+id/mylistview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</ListView>
You then need a layout for a row/entry in the list View (ie it equates to a cursor row). A simple example that caters for two db columns (Name and Order) :-
<?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="#dimen/standard_listview_row_height"
android:paddingBottom="#dimen/standard_listview_row_padding_vertical"
android:paddingLeft="#dimen/standard_listview_row_padding_horizontal"
android:paddingRight="#dimen/standard_listview_row_padding_horizontal"
android:paddingTop="#dimen/standard_listview_row_padding_vertical">
<!-- Aisle Name -->
<TextView
android:id="#+id/aisle_name_entry"
android:layout_width="#dimen/standard_dummy_size"
android:layout_height="match_parent"
android:layout_weight="0.89"
android:textSize="#dimen/standard_listview_text_size"
android:textStyle="bold" />
<!-- Aisle Order-->
<TextView
android:id="#+id/aisle_order_entry"
android:layout_width="#dimen/standard_dummy_size"
android:layout_height="match_parent"
android:layout_weight="0.1"
android:gravity="end"
android:textSize="#dimen/standard_listview_text_size"
android:visibility="visible"/>
</LinearLayout>
You need an Adapter.A Cursor Adapater basically places the data from the DB cursor into the appropriate views. Here's an Adapter for the above:-
class AislesCursorAdapter extends CursorAdapter {
public AislesCursorAdapter(Context context, Cursor cursor, int flags) {
super(context, cursor, 0);
}
#Override
public View getView(int position, View convertview, ViewGroup parent) {
View view = super.getView(position, convertview, parent);
Context context = view.getContext();
if (position % 2 == 0) {
view.setBackgroundColor(ContextCompat.getColor(context, R.color.colorlistviewroweven));
} else {
view.setBackgroundColor(ContextCompat.getColor(context, R.color.colorlistviewrowodd));
}
return view;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView textviewaislename = (TextView) view.findViewById(R.id.aisle_name_entry);
TextView textviewaisleorder = (TextView) view.findViewById(R.id.aisle_order_entry);
textviewaislename.setText(cursor.getString(ShopperDBHelper.AISLES_COLUMN_NAME_INDEX));
textviewaisleorder.setText(cursor.getString(ShopperDBHelper.AISLES_COLUMN_ORDER_INDEX));
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.activity_aisle_list_entry, parent, false);
}
}
Note! getView method isn't required. Here it's used to alternate the background colour. Additionally ShopperDBHelper.??????_ORDER equates to the offset of the respective column in the DB cursor. The inflated layout (R.layout.activity_aisle_list_entry) is the 2nd layout (as above).
You tie this together in the respective activity by creating the DB cursor, creating an adapter instance using the DB cursor and then setting the ListView to use that adapter e.g. :-
Cursor aislescsr = shopperdb.getAislesPerShopAsCursor(csr.getInt(ShopperDBHelper.SHOPS_COLUMNN_ID_INDEX));
ListView lv = (ListView) findViewById(R.id.aislelist_listview);
AislesCursorAdapter aisleadapter = new AislesCursorAdapter(lv.getContext(), aislescsr, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
lv.setAdapter(aisleadapter);
As for a clickable image you can add this to the entry layout and set the onClick attribute to the name of a method in the activity (not the only wau, but perhaps the simplest). e.g. (this is for a TextView as opposed to an image) :-
<TextView
android:id="#+id/shoppinglist_deletebutton"
android:layout_width="#dimen/standard_dummy_size"
android:layout_height="#dimen/shoppinglist_listview_button_height"
android:layout_weight="0.05"
android:singleLine="true"
android:text="#string/standarddeletetext"
android:gravity="center"
android:textSize="#dimen/standard_subsubsubheading_text_size"
android:textStyle="bold"
android:background="#color/colorRequiredLabel"
android:textColor="#color/colorNormalButtonText"
android:onClick="sledelete"/>
Here's the respective sledelete method :-
public void sledelete(View view) {
Integer tag = (Integer)view.getTag();
shoppinglistcsr.moveToPosition(tag);
shopperdb.setShopListEntryAsComplete(shoppinglistcsr.getLong(0));
shoppinglistcsr = shopperdb.getShoppingList();
currentsla.swapCursor(shoppinglistcsr);
}
Note! the method is only passed the view and importantly NOT the position. Hence the getTag (tag is set to position in the adpter, example to follow). Note that the last 2 lines refreshes the Listview ie, gets new cursor from DB, and then swaps to the new cursor (you can also use changeCursor and onNotifyDataSetChanged).
Here's the tag setting code in the adapter. This is in the bindView method (and sets the tags for 3 TextViews) :-
public void bindView(View view,Context context, Cursor cursor) {
int pos = cursor.getPosition();
.........
donebtntv.setTag(pos);
deletebtntv.setTag(pos);
replacebtntv.setTag(pos);
Alternately you could set the Tag(s) this in the getView method, which has the position passed to it (so you wouldn't need int pos = cursor.getPosition )
I try a Custom Simple Cursor adapter for Listview. I get datas from Database and try to show my listview But I got some exception. İf u help me I will so happy thanks. Here is code:
public class cursorDeneme extends ListActivity{
Cursor c ;
String sutunlar[] = new String[]{"name"};
int to[] = new int[]{R.id.name_entry};
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.cursorden);
DB_E db = new DB_E(this);// database class
try {
db.openReadable();
c=db.veriAlCursor();// gets Cursor from database
mySimpleCursorAdapter adapter = new mySimpleCursorAdapter(this, R.layout.cursorden, c, sutunlar, to);
db.close();
this.setListAdapter(adapter);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}}
Here is database class:
public class DB_E {
public static final String KEY_ROWID ="id";
public static final String KEY_WORK_OUT ="workout"; //Hangi workout
public static final String KEY_NAME ="name";
public static final String KEY_REP ="rep";
public static final String KEY_WEIGHT ="weight";
public Cursor veriAlCursor(){ //get datas
Cursor c = ourDataBase.query(DATABASE_TABLE, sutunlar, null, null, null, null, null);
return c;
}
public Cursor veriAlCursor(String workout){ //get datas
workout ="'%"+workout+"%'";
Cursor c = ourDataBase.query(DATABASE_TABLE, sutunlar, KEY_WORK_OUT+" LIKE "+workout, null, null, null, null);
return c;
}
And mySimpleCustomAdapter:
public class mySimpleCursorAdapter extends SimpleCursorAdapter {
Cursor c;
Context context;
Activity activity;
cursorDeneme cursorD ;
public mySimpleCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
this.c=c;
this.activity=(Activity)context;
this.context=context;
this.cursorD =(cursorDeneme)context;
}
#Override
public View getView(int position , View convertView , ViewGroup parent){
if(convertView == null)
convertView.inflate(context, R.layout.liste, null);
View row=convertView;
c.moveToPosition(position);
int iName =c.getColumnIndex("name");
TextView name =(TextView)convertView.findViewById(R.id.name_entry);
name.setText(c.getString(iName));
return (row);
}
and Xml :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#848484" >
<LinearLayout
android:id="#+id/linear1"
android:layout_width="240dp"
android:layout_height="350dp"
android:background="#CEF6E3"
android:layout_marginLeft="40dp"
android:layout_marginTop="20dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="20dp"
>
<ListView
android:id="#+id/listView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#151515"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
></ListView>
</LinearLayout>
</LinearLayout>
Error log : Unhandled event loop Exception
Invalid preference page path: XML Syntax
...
Thanks.
I am working on an application in which i need to fetch all the contacts from the contact book and display. i want the user to select some contacts and add them in a group which is saved in db.
i have created a custom list view- contactitem.xml-
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<TextView
android:id="#+id/contactname"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:layout_marginLeft="20dp"
android:ellipsize="end"
android:singleLine="true"
android:clickable="true"/>
<TextView
android:id="#+id/contactnum"
android:layout_width="wrap_content"
android:textColor="#color/White"
android:clickable="true"
android:layout_gravity="center_vertical"
android:layout_height="wrap_content"/>
<Button
android:id="#+id/add"
android:layout_width="wrap_content"
android:layout_height="35dp"
android:text="#string/add_contacts"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:focusable="false"
android:focusableInTouchMode="false"/>
</LinearLayout>
i have a SelectContact class for fetching contacts from Contact book-
public class SelectContacts extends Activity implementsOnItemClickListener {
private List<Contact> list = new ArrayList<Contact>();
private ListView contact_list;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.selectcontacts);
contact_list=(ListView)findViewById(R.id.contactsListView);
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
cur.moveToFirst();
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?", new String[]{id}, null);
pCur.moveToFirst();
while (pCur.moveToNext()) {
String number=pCur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
Contact c=new Contact();
c.setContactName(name);
c.setContactNum(number);
list.add(c);
}
pCur.close();
}
ContactAdapter contactAdapter=new ContactAdapter(this, R.layout.contactitem, list);
contact_list.setAdapter(contactAdapter);
}
}
}
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
}
}
and implemented a custom adapter- ContactAdapter-
public class ContactAdapter extends ArrayAdapter<Contact>{
List<Contact> items;
LayoutInflater mInflater ;
Context context;
int layoutResourceId;
public ContactAdapter(Context context, int layoutResourceId, List<Contact> items) {
super(context, layoutResourceId, items);
this.layoutResourceId=layoutResourceId;
this.items = items;
this.context=context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder = new ViewHolder();
if(row==null){
mInflater = ((Activity)context).getLayoutInflater();
row = mInflater.inflate(layoutResourceId, parent, false);
holder.name = (TextView) row.findViewById(R.id.contactname);
holder.number = (TextView) row.findViewById(R.id.contactnum);
holder.add=(Button)row.findViewById(R.id.add);
row.setTag(holder);
}else{
holder=(ViewHolder)row.getTag();
}
String name=items.get(position).getContactName();
String number=items.get(position).getContactNum();
holder.name.setText(name);
holder.number.setText(number);
holder.add.setText("Add");
return row;
}
static class ViewHolder{
TextView name;
TextView number;
Button add;
}
}
here Contact is a simple POJO-
public class Contact {
private String contactName;
private String contactNum;
public String getContactName() {
return contactName;
}
public void setContactName(String contactName) {
this.contactName = contactName;
}
public String getContactNum() {
return contactNum;
}
public void setContactNum(String contactNum) {
this.contactNum = contactName;
}
}
i am a newbie in android..
Here when i start SelectContact activity it cannot display contact on the UI.. please help me guys...
Thanks
I will insist you to use List<Contact> list = new ArrayList<Contact>(); instead of using ArrayList<HashMap<String, Contact>> list= new ArrayList<HashMap<String, Contact>>();
You just need to fetch the Contact details and set the values to the Contact Class and add to the ArrayList object. And then just pass the list Object to ArrayAdapter class and use it. This is the easiest way, you are making it a bit complex using HashMap in this case.
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.