Android AdapterView cannot display database records in some device - android

I would like to ask some question about AdapterView.
In my application, there is an activity which retrieve data from database and display them in AdapterView.
However, when i install the application in different devices, I found that the part I have just mentioned could only function on some devices. The others cannot show the database results.
Here is my code:
private void showResults(String query) {
Cursor cursor = searchCustByInputText(query);
if (cursor == null) {
//
} else {
// Specify the columns we want to display in the result
String[] from = new String[] {
"cust_code",
"chinese_name"};
// Specify the Corresponding layout elements where we want the columns to go
int[] to = new int[] {
R.id.scust_code,
R.id.schinese_name};
// Create a simple cursor adapter for the definitions and apply them to the ListView
SimpleCursorAdapter customers = new SimpleCursorAdapter(this,R.layout.cust_list_item, cursor, from, to);
mListView.setAdapter(customers);
// Define the on-click listener for the list items
mListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Cursor c = (Cursor) mListView.getItemAtPosition(position);
String cust_code = c.getString(c.getColumnIndex("cust_code"));
if (callFromAct.equals("Main")) {
String pay_term = c.getString(c.getColumnIndex("pay_term"));
String chinese_name = c.getString(c.getColumnIndex("chinese_name"));
String english_name = c.getString(c.getColumnIndex("english_name"));
String address_1 = c.getString(c.getColumnIndex("address_1"));
String address_2 = c.getString(c.getColumnIndex("address_2"));
String address_3 = c.getString(c.getColumnIndex("address_3"));
String address_4 = c.getString(c.getColumnIndex("address_4"));
String contact = c.getString(c.getColumnIndex("contact"));
String telephone = c.getString(c.getColumnIndex("telephone"));
String last_order_date = c.getString(c.getColumnIndex("last_order_date"));
//Pass data to another Activity
Intent it = new Intent(CustEnqActivity.this, CustEnqDetailsActivity.class);
Bundle bundle = new Bundle();
bundle.putString("cust_code", cust_code);
bundle.putString("pay_term", pay_term);
bundle.putString("chinese_name", chinese_name);
bundle.putString("english_name", english_name);
bundle.putString("address_1", address_1);
bundle.putString("address_2", address_2);
bundle.putString("address_3", address_3);
bundle.putString("address_4", address_4);
bundle.putString("contact", contact);
bundle.putString("telephone", telephone);
bundle.putString("last_order_date", last_order_date);
it.putExtras(bundle);
startActivity(it);
}
else {
returnToCallingAct(cust_code);
}
//searchView.setQuery("",true);
}
});
}
}
Besides, I discovered there were two warnings in my logcat.
The constructor SimpleCursorAdapter(Context, int, Cursor, String[], int[]) is deprecated
AdapterView is a raw type. References to generic type AdapterView should be parameterized
Are they related to the problem?

Try to create a class that extends BaseAdapter and use ViewHolders for performance
eg:
public class MyBaseAdapter extends BaseAdapter {
ArrayList<ListData> myList = new ArrayList<ListData>();
LayoutInflater inflater;
Context context;
public MyBaseAdapter(Context context, ArrayList<ListData> myList) {
this.myList = myList;
this.context = context;
inflater = LayoutInflater.from(this.context); // only context can also be used
}
#Override
public int getCount() {
return myList.size();
}
#Override
public ListData 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) {
MyViewHolder mViewHolder;
if(convertView == null) {
convertView = inflater.inflate(R.layout.layout_list_item, null);
mViewHolder = new MyViewHolder();
convertView.setTag(mViewHolder);
} else {
mViewHolder = (MyViewHolder) convertView.getTag();
}
mViewHolder.tvTitle = detail(convertView, R.id.tvTitle, myList.get(position).getTitle());
mViewHolder.tvDesc = detail(convertView, R.id.tvDesc, myList.get(position).getDescription());
mViewHolder.ivIcon = detail(convertView, R.id.ivIcon, myList.get(position).getImgResId());
return convertView;
}
// or you can try better way
private TextView detail(View v, int resId, String text) {
TextView tv = (TextView) v.findViewById(resId);
tv.setText(text);
return tv;
}
private ImageView detail(View v, int resId, int icon) {
ImageView iv = (ImageView) v.findViewById(resId);
iv.setImageResource(icon); //
return iv;
}
private class MyViewHolder {
TextView tvTitle, tvDesc;
ImageView ivIcon;
}
}
More info/example:
http://www.pcsalt.com/android/listview-using-baseadapter-android/#sthash.lNGSCiyB.dpbs

Related

Get the id from listview when an item is clicked

I have a column in the database _id I would like to get this id when an list view item is clicked. Currently the code below is giving me the position of the item. I' am still playing around with it I have a feeling something is wrong in the method 'getItemId'
onCreate method
ArrayList<String> arrayCatNames = new ArrayList<String>();
String query = "SELECT * FROM category ORDER BY name ASC";
Cursor results = myDB.rawQuery(query, null);
while(results.moveToNext()){
String catName = results.getString(results.getColumnIndex("name"));
arrayCatNames.add(catName);
}
String[] catNamesArr = new String[arrayCatNames.size()];
catNamesArr = arrayCatNames.toArray(catNamesArr);
lvActivityCategory = (ListView) findViewById(R.id.lvActivityCategory);
lvActivityCategory.setAdapter(new categoryCursorAdaptor(this, catNamesArr));
lvActivityCategory.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(getApplicationContext(), categoryActivity.class);
intent.putExtra("category_id", id);
Context context = getApplicationContext();
String s = Long.toString(position);
CharSequence text = s;
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
});
categoryCursorAdaptor
class categoryCursorAdaptor extends BaseAdapter {
Context context;
String[] data;
private static LayoutInflater inflater = null;
public categoryCursorAdaptor(Context context, String[] data) {
this.context = context;
this.data = data;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return data.length;
}
#Override
public Object getItem(int position) {
return data[position];
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
if (vi == null) vi = inflater.inflate(R.layout.item_category, null);
TextView text = (TextView) vi.findViewById(R.id.itemListCategory);
text.setText(data[position]);
return vi;
}
}
ArrayList<String> arrayCatNames = new ArrayList<String>();
ArrayList<Integer> arrayIds = new ArrayList<Integer>();
String query = "SELECT * FROM category ORDER BY name ASC";
Cursor results = myDB.rawQuery(query, null);
while(results.moveToNext()){
String catName = results.getString(results.getColumnIndex("name"));
int Ids = results.getInt(results.getColumnIndex("_id"));
arrayCatNames.add(catName);
arrayIds.add(Ids);
}
Then in your onItemClick
yourCategoryId = arrayIds.get(position);
You need to declare your ArrayList arrayIds at the top, before your onCreate

Picasso loading of image spawned inside AsyncTask

So I am trying to use the Picasso Library for image downloading and caching. In order to get the contactUri to pass to Picasso I need to make a query to the Contacts Content Provider. Since I don't want to block the main UI thread to get the contactId, I have put this in an AsyncTask. And once I get that contactId, I make the call to Picasso in the onPostExecute() method of the AsyncTask.
However, I am noticing a flickering that shows up when I scroll through my ListView quickly. It seems to me that there is an issue with the ViewHolder since the recycled views are displaying the previous image before setting the appropriate image. Is there anyway to avoid this?
public class ConversationThreadsCursorAdapter extends SimpleCursorAdapter {
// region Constants
private static final int RECIPIENT_IDS_COLUMN_INDEX = 3;
private static final int ID2_COLUMN_INDEX = 0;
private static final int ADDRESS_COLUMN_INDEX = 1;
// endregion
// region Variables
private final String DEBUG_TAG = getClass().getSimpleName().toString();
private Context mContext;
protected Drawable mDefaultPicDrawable;
protected ContentResolver mContentResolver;
protected LinearLayout.LayoutParams mContactPicLayoutParams;
// endregion
// region Constructors
public ConversationThreadsCursorAdapter(Context context, int layout,
Cursor c, String[] from, int[] to, int flags) {
super(context, layout, c, from, to, flags);
mContext = context;
mDefaultPicDrawable = mContext.getResources().getDrawable(
R.drawable.ic_contact_picture);
mContactPicLayoutParams = new LinearLayout.LayoutParams(
mDefaultPicDrawable.getIntrinsicWidth(),
mDefaultPicDrawable.getIntrinsicHeight());
}
// endregion
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView == null) {
convertView = mLayoutInflater.inflate(R.layout.simple_message, null);
// Creates a ViewHolder and store references to the children
// views we want to bind data to.
viewHolder = setupViewHolder(convertView);
convertView.setTag(viewHolder);
} else {
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
viewHolder = (ViewHolder) convertView.getTag();
viewHolder.task.cancel(true);
}
mCursor = getCursor();
mCursor.moveToPosition(position);
viewHolder.position = position;
String recipient_ids = mCursor.getString(RECIPIENT_IDS_COLUMN_INDEX);
String[] recipients = recipient_ids.split(" ");
viewHolder.task = new AddressFetcherTask(viewHolder, position);
viewHolder.task.execute(recipients);
return convertView;
}
// region Helper Methods
private ViewHolder bindUIElements(View convertView) {
ViewHolder viewHolder = new ViewHolder();
viewHolder.contactBadge = (QuickContactBadge) convertView.findViewById(R.id.contact_pic);
return viewHolder;
}
private ViewHolder setupViewHolder(View convertView) {
ViewHolder viewHolder = bindUIElements(convertView);
viewHolder.contactBadge.setLayoutParams(mContactPicLayoutParams);
return viewHolder;
}
// endregion
// region Inner Classes
private class ViewHolder {
QuickContactBadge contactBadge;
int position;
}
private class AddressFetcherTask extends AsyncTask < String[], Void, Integer > {
private ViewHolder mViewHolder;
private int mPosition;
public AddressFetcherTask(ViewHolder viewHolder, int position) {
mViewHolder = viewHolder;
mPosition = position;
}
#Override
protected Integer doInBackground(String[]...recipients) {
String recipient = recipients[0][0];
Log.d(DEBUG_TAG, "recipient is " + recipient);
Cursor c = mContentResolver.query(
Uri.parse("content://mms-sms/canonical-addresses"), null, "_id = " + recipient, null, null);
String _id = "";
String address = "";
while (c.moveToNext()) {
_id = c.getString(ID2_COLUMN_INDEX);
address = c.getString(ADDRESS_COLUMN_INDEX);
}
c.close();
int contactId;
if (address != null) {
contactId = ContactsUtils.getContactId(mContext, address, "address");
} else {
contactId = Integer.valueOf(address);
}
return contactId;
}
#Override
protected void onPostExecute(Integer contactId) {
if (mViewHolder.position == mPosition) {
Picasso.with(mContext)
.load(getContactUri(contactId))
.placeholder(R.drawable.ic_contact_picture)
.into(mViewHolder.contactBadge);
}
}
}
// endregion
}
Just set the imageview to null in within getView and it should remove what you are experiencing for the most part you'll be right.
The other tiny tiny corner case aspect is that when your asynctask arrives at postExecute, the view might still exist, but it might have already been assigned a different contact to load up (it's been recycled).
You need to put some kind of tag in the viewholder, and then check that it is still the same when you go to set it in postexecute.
To remove the fade in, you need to remove the asynctask from the getview. You need to be able to call picasso within getview, which means having your data ready before arriving at getview.
The below, not quite sure if it will compile, I've done it in a text editor.
But bassically I'm caching results in mCachedContactIds and just reloading the whole table if I need a new one. I've typically found this to be robust. But you can also call the picasso code which I've commented out
public class ConversationThreadsCursorAdapter extends SimpleCursorAdapter {
// region Constants
private static final int RECIPIENT_IDS_COLUMN_INDEX = 3;
private static final int ID2_COLUMN_INDEX = 0;
private static final int ADDRESS_COLUMN_INDEX = 1;
private HashMap<String, Integer> mCachedContactIds = new HashMap<String, Integer>();
// endregion
// region Variables
private final String DEBUG_TAG = getClass().getSimpleName().toString();
private Context mContext;
protected Drawable mDefaultPicDrawable;
protected ContentResolver mContentResolver;
protected LinearLayout.LayoutParams mContactPicLayoutParams;
// endregion
// region Constructors
public ConversationThreadsCursorAdapter(Context context, int layout,
Cursor c, String[] from, int[] to, int flags) {
super(context, layout, c, from, to, flags);
mContext = context;
mDefaultPicDrawable = mContext.getResources().getDrawable(
R.drawable.ic_contact_picture);
mContactPicLayoutParams = new LinearLayout.LayoutParams(
mDefaultPicDrawable.getIntrinsicWidth(),
mDefaultPicDrawable.getIntrinsicHeight());
}
// endregion
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView == null) {
convertView = mLayoutInflater.inflate(R.layout.simple_message, null);
// Creates a ViewHolder and store references to the children
// views we want to bind data to.
viewHolder = setupViewHolder(convertView);
convertView.setTag(viewHolder);
} else {
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
viewHolder = (ViewHolder) convertView.getTag();
viewHolder.task.cancel(true);
viewHolder.contactBadge.setImageDrawable(mDefaultPicDrawable);
}
mCursor = getCursor();
mCursor.moveToPosition(position);
viewHolder.position = position;
String recipient_ids = mCursor.getString(RECIPIENT_IDS_COLUMN_INDEX);
String[] recipients = recipient_ids.split(" ");
String recipient = recipients[0];
if(mCachedContactIds.get(recipient) != null){
Picasso.with(mContext)
.load(getContactUri(mCachedContactIds.get(recipient)))
.placeholder(R.drawable.ic_contact_picture)
.into(mViewHolder.contactBadge);
} else {
viewHolder.task = new AddressFetcherTask(viewHolder, position);
viewHolder.task.execute(recipients);
}
return convertView;
}
// region Helper Methods
private ViewHolder bindUIElements(View convertView) {
ViewHolder viewHolder = new ViewHolder();
viewHolder.contactBadge = (QuickContactBadge) convertView.findViewById(R.id.contact_pic);
return viewHolder;
}
private ViewHolder setupViewHolder(View convertView) {
ViewHolder viewHolder = bindUIElements(convertView);
viewHolder.contactBadge.setLayoutParams(mContactPicLayoutParams);
return viewHolder;
}
// endregion
// region Inner Classes
private class ViewHolder {
QuickContactBadge contactBadge;
int position;
AddressFetcherTask task;
}
private class AddressFetcherTask extends AsyncTask < String[], Void, Integer > {
private ViewHolder mViewHolder;
private int mPosition;
private String mRecipient;
public AddressFetcherTask(ViewHolder viewHolder, int position) {
mViewHolder = viewHolder;
mPosition = position;
}
#Override
protected Integer doInBackground(String[]...recipients) {
mRecipient = recipients[0][0];
Log.d(DEBUG_TAG, "recipient is " + recipient);
Cursor c = mContentResolver.query(
Uri.parse("content://mms-sms/canonical-addresses"), null, "_id = " + mRecipient, null, null);
String _id = "";
String address = "";
while (c.moveToNext()) {
_id = c.getString(ID2_COLUMN_INDEX);
address = c.getString(ADDRESS_COLUMN_INDEX);
}
c.close();
int contactId;
if (address != null) {
contactId = ContactsUtils.getContactId(mContext, address, "address");
} else {
contactId = Integer.valueOf(address);
}
return contactId;
}
#Override
protected void onPostExecute(Integer contactId) {
if (mViewHolder.position == mPosition) {
mCachedContactIds.put(mRecipient, contactId);
Picasso.with(mContext)
.load(getContactUri(mCachedContactIds.get(recipient)))
.placeholder(R.drawable.ic_contact_picture)
.into(mViewHolder.contactBadge);
}
}
}
// endregion
}
Or if all that's bugging you left is the fade from picasso, then add noFade() to the request.

setting text view according its position of the row a listview filled by SimpleCursorAdapter database with click on the row

setting the text view according its position in of the row a list view filled from SimpleCursorAdapter from database on the click of the onlistitemclicked
my custom list view has an image& textview for a name and another invisible text view which will be visible and be setting with a different number on the row clicked only but the problem is that when i clicked any row the text appeared on the view at the first row only whatever the row i clicked
and I tried to use the set and get methods but i found its used for the Base Adapter.
and the textview which will visible is not from data base
can some one tell me how to do it please
here is a part of the code
public class Select_players_two extends ListActivity
{
protected static class RowViewHolder
{
public TextView tvOne;
public TextView tvTwo;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(android.view.Menu menu)
{
// TODO Auto-generated method stub
return super.onCreateOptionsMenu(menu);
}
public class CustConAdpterSelect extends SimpleCursorAdapter
{
int i = 0;
int count;
private int layout;
LayoutInflater inflator;
final SQLiteConnector sqlCon = new SQLiteConnector(mContext);
private ImageButton editBtn;
private ImageButton delBtn;
int id ;
TextView txt_select;
CharSequence txt_char;
static final String KEY_No = "playerNo";
public CustConAdpterSelect(Context context, int layout, Cursor c,
String[] from, int[] to, int flags)
{
super(context, layout, c, from, to,0);
this.layout = layout;
inflator= LayoutInflater.from(context);
}
public View newView(Context context, Cursor cursor, ViewGroup parent)
{
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View retView = inflater.inflate(R.layout.lv_name_photo, parent, false);
RowViewHolder holder = new RowViewHolder();
holder.tvOne = (TextView) retView.findViewById(R.id.name);
holder.tvTwo = (TextView) retView.findViewById(R.id.txt_number);
// holder.tvOne.setOnClickListener(tvOneLapOnClickListener);
retView.setTag(holder);
return retView;
}
#Override
public void bindView(View v, final Context context, Cursor c)
{
editBtn=(ImageButton) v.findViewById(R.id.edit_btn);
if( editBtn.getVisibility() == View.VISIBLE )
editBtn.setVisibility(View.INVISIBLE);
else
editBtn.setVisibility(View.INVISIBLE);
//set delete button invisble
delBtn=(ImageButton) v.findViewById(R.id.del_btn);
if( delBtn.getVisibility() == View.VISIBLE )
delBtn.setVisibility(View.INVISIBLE);
else
delBtn.setVisibility(View.INVISIBLE);
//final int
id = c.getInt(c.getColumnIndex(Contacts.ID));
final String name = c.getString(c.getColumnIndex(Contacts.NAME));
final String phone = c.getString(c.getColumnIndex(Contacts.PHONE));
final String email = c.getString(c.getColumnIndex(Contacts.MAIL));
final String fb = c.getString(c.getColumnIndex(Contacts.FB));
final byte[] image = c.getBlob(c.getColumnIndex(Contacts.IMAGE));
ImageView iv = (ImageView) v.findViewById(R.id.photo);
if (image != null)
{
if (image.length > 3)
{
iv.setImageBitmap(BitmapFactory.decodeByteArray(image, 0,image.length));
}
}
TextView tname = (TextView) v.findViewById(R.id.name);
tname.setText(name);
TextView tphone = (TextView) v.findViewById(R.id.phone);
tphone.setText(phone);
TextView temail = (TextView) v.findViewById(R.id.email);
temail.setText(email);
txt_select=(TextView)v.findViewById(R.id.txt_number);
// final SQLiteConnector sqlCon = new SQLiteConnector(context);
//for( i = 0; i <=4; i++)
/*
v.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
//onitem clicked
txt_char = txt_select.getText();
{
if (txt_char != null)
{
int txt_int = Integer.parseInt(txt_char.toString());
int count = txt_int;
Log.d("count1",String.valueOf(count));
count++;
txt_select.setText(String.valueOf(count));
Log.d("count",String.valueOf(count));
if( txt_select.getVisibility() == View.INVISIBLE )
txt_select.setVisibility(View.VISIBLE);
else
txt_select.setVisibility(View.INVISIBLE);
Log.d("number", String.valueOf(i));
}
/* if( txt_select.getVisibility() == View.INVISIBLE )
txt_select.setVisibility(View.VISIBLE);
else
txt_select.setVisibility(View.INVISIBLE);
i++;
Log.d("number", String.valueOf(i));*/
/* }
}
});
*/
}
#Override
public View getView(final int position, View convertView, ViewGroup parent)
{
final View view = super.getView(position, convertView, parent);
final TextView textView = (TextView)view.findViewById(R.id.txt_number);
/* textView.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
Log.i("Click", "TextView clicked on row " + position);
// textView.setTag(position);
txt_char = txt_select.getText();
Log.d("txt", txt_char.toString());
if (txt_char != null)
{
int txt_int = Integer.parseInt(txt_char.toString());
Log.d("txt2", txt_char.toString());
int count = txt_int;
Log.d("count1",String.valueOf(count));
count++;
txt_select.setText(String.valueOf(count));
CharSequence txt_char2 = txt_select.getText();
Log.d("ttxt", txt_char2.toString());
Log.d("count",String.valueOf(count));
if( txt_select.getVisibility() == View.INVISIBLE )
txt_select.setVisibility(View.VISIBLE);
else
txt_select.setVisibility(View.INVISIBLE);
Log.d("number", String.valueOf(i));
i++;
}
}*/
// }); // TODO Auto-generated method stub
return view;
}
private OnClickListener tvOneLapOnClickListener = new OnClickListener()
{
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
// get the RowViewHolder
RowViewHolder holder = new RowViewHolder();
// Get the holder for the row
holder = (RowViewHolder) ((View) v.getParent()).getTag();
if (holder.tvOne.getVisibility() == View.INVISIBLE)
holder.tvOne.setVisibility(View.VISIBLE);
else
holder.tvOne.setVisibility(View.INVISIBLE);
}
};
}
}
that is the database class "SQLiteConnector"
public class SQLiteConnector
{
private SQLiteDatabase db;
private SQLiteHelper sqlHp,sqlhpc;
private Cursor cur,curc;
public SQLiteConnector(Context context)
{
sqlHp = new SQLiteHelper(context, Contacts.DB_NAME, null, 1);
sqlhpc = new SQLiteHelper(context, Contacts.DB_NAME, null, 1);
}
// insert new player in the list//
public void insertContact(String name, String phone, String mail,String fb,byte[] blob) {
ContentValues cv = new ContentValues();
cv.put(Contacts.NAME, name);
cv.put(Contacts.PHONE, phone);
cv.put(Contacts.MAIL, mail);
cv.put(Contacts.FB, fb);
cv.put(Contacts.IMAGE,blob);
db = sqlHp.getWritableDatabase();
db.insert(Contacts.TABLE, null, cv);
db.close();
}
// insert the score sheet //
public void insertContact_score(String score, String num_call, String num_collection ,String shape_type,
String score_sec, String num_call_sec, String num_collection_sec ,String shape_type_sec,
String score_third, String num_call_third, String num_collection_third ,String shape_type_third,
String score_forth, String num_call_forth, String num_collection_forth ,String shape_type_forth)
{
ContentValues cvscore = new ContentValues();
cvscore.put(Contacts.SCORE_st, score);
cvscore.put(Contacts.NUM_CALL_st, num_call);
cvscore.put(Contacts.NUM_COLLECTION_st, num_collection);
cvscore.put(Contacts.SHAPE_CALL_st, shape_type);
cvscore.put(Contacts.SCORE_sec, score_sec);
cvscore.put(Contacts.NUM_CALL_sec, num_call_sec);
cvscore.put(Contacts.NUM_COLLECTION_sec, num_collection_sec);
cvscore.put(Contacts.SHAPE_CALL_sec, shape_type_sec);
cvscore.put(Contacts.SCORE_third, score_third);
cvscore.put(Contacts.NUM_CALL_third, num_call_third);
cvscore.put(Contacts.NUM_COLLECTION_third, num_collection_third);
cvscore.put(Contacts.SHAPE_CALL_third,shape_type_third);
cvscore.put(Contacts.SCORE_forth, score_forth);
cvscore.put(Contacts.NUM_CALL_forth, num_call_forth);
cvscore.put(Contacts.NUM_COLLECTION_forth, num_collection_forth);
cvscore.put(Contacts.SHAPE_CALL_forth,shape_type_forth);
//cvscore.put(Contacts.IMAGE,blob);
db = sqlhpc.getWritableDatabase();
db.insert(Contacts.TABLESCORE, null, cvscore);
db.close();
}
public void updateContact_score(long id,String score, String num_call, String num_collection ,String shape_type,
String score_sec, String num_call_sec, String num_collection_sec ,String shape_type_sec,
String score_third, String num_call_third, String num_collection_third ,String shape_type_third,
String score_forth, String num_call_forth, String num_collection_forth ,String shape_type_forth)
{
ContentValues cvscore = new ContentValues();
cvscore.put(Contacts.SCORE_st, score);
cvscore.put(Contacts.NUM_CALL_st, num_call);
cvscore.put(Contacts.NUM_COLLECTION_st, num_collection);
cvscore.put(Contacts.SHAPE_CALL_st, shape_type);
cvscore.put(Contacts.SCORE_sec, score_sec);
cvscore.put(Contacts.NUM_CALL_sec, num_call_sec);
cvscore.put(Contacts.NUM_COLLECTION_sec, num_collection_sec);
cvscore.put(Contacts.SHAPE_CALL_sec, shape_type_sec);
cvscore.put(Contacts.SCORE_third, score_third);
cvscore.put(Contacts.NUM_CALL_third, num_call_third);
cvscore.put(Contacts.NUM_COLLECTION_third, num_collection_third);
cvscore.put(Contacts.SHAPE_CALL_third,shape_type_third);
cvscore.put(Contacts.SCORE_forth, score_forth);
cvscore.put(Contacts.NUM_CALL_forth, num_call_forth);
cvscore.put(Contacts.NUM_COLLECTION_forth, num_collection_forth);
cvscore.put(Contacts.SHAPE_CALL_forth,shape_type_forth);
//cvscore.put(Contacts.IMAGE,blob);
db = sqlhpc.getWritableDatabase();
db.update(Contacts.TABLESCORE, cvscore, Contacts.ID+"="+ id, null);
db.close();
}
public void updateContact(long id,String name, String phone, String mail,String fb,byte[] blob) {
ContentValues cv = new ContentValues();
cv.put(Contacts.NAME, name);
cv.put(Contacts.PHONE, phone);
cv.put(Contacts.MAIL, mail);
cv.put(Contacts.FB, fb);
cv.put(Contacts.IMAGE,blob);
db = sqlHp.getWritableDatabase();
db.update(Contacts.TABLE, cv, Contacts.ID+"="+ id, null);
db.close();
}
public Cursor getAllContacts() {
db = sqlHp.getReadableDatabase();
cur=db.query(Contacts.TABLE,null, null,null, null, null, "name");
return cur;
}
public Cursor getAllScores() {
db = sqlhpc.getReadableDatabase();
curc=db.query(Contacts.TABLESCORE,null, null,null, null, null, "score_st");
return curc;
}
public void deletescore(long id) {
System.out.println("DELETE ");
db = sqlhpc.getWritableDatabase();
db.delete(Contacts.TABLESCORE, "_id="+id , null);
db.close();
}
public Cursor getOneContact(long id) {
db = sqlHp.getReadableDatabase();
cur=db.query(Contacts.TABLE, null, "_id="+ id, null, null, null,null);
return cur;
}
public void deleteContact(long id) {
System.out.println("DELETE ");
db = sqlHp.getWritableDatabase();
db.delete(Contacts.TABLE, "_id="+id , null);
db.close();
}
}
I believe what you need to do is use the Tag facility of the row view container to identify the textview it contains and then retrieve it in the listener to identify the correct textview. The way I've done it is to use a holder for the row contained views, so you can access any that you need. For example:
protected static class RowViewHolder {
public TextView tvOne;
public TextView tvTwo;
}
Then in your newView method, populate the holder and set the Tag to it:
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View retView = inflater.inflate(R.layout.single_row_item, parent, false);
RowViewHolder holder = new RowViewHolder();
holder.tvOne = (TextView) retView.findViewById(R.id.name);
holder.tvTwo = (TextView) retView.findViewById(R.id.txt_number);
retView.setTag(holder);
return retView;
}
In your listener then you can access the correct textview:
public void onClick(View v) {
ListView lv = (ListView) v.getParent();
final int position = lv.getPositionForView((View) v.getParent());
// get the RowViewHolder
RowViewHolder holder = new RowViewHolder();
holder = (RowViewHolder) ((View) v.getParent()).getTag();
if(holder.tvOne.getVisibility() == View.INVISIBLE ) {
holder.tvOne.setVisibility(View.VISIBLE);
}
else
{
holder.tvOne.setVisibility(View.INVISIBLE);
}
}
Apologies, but I've not been able to test this code but I hope it gives you a pointer to the process. You shouldn't need the RowViewHolder but I've included it so you or others can see how to access multiple views within the row.
You may find the this video helpful The World of ListView I think you'll find the relevant discussion at about 4:10 in which describes how the views are res-used and how index, position etc. relate.
I also found one of the answers to this question helpful Android: ListView elements with multiple clickable buttons
There are multiple ways of doing this. The way I was suggesting assumes you have a single code module for the activity containing the CustConAdpterSelect class. So the structure looks something like this.
package com.example.totastest;
// imports
public class Copy_2_of_MainActivity extends Activity {
protected static class RowViewHolder
{
public TextView tvOne;
public TextView tvTwo;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public class CustConAdpterSelect extends SimpleCursorAdapter
{
// ...
public CustConAdpterSelect(Context context, int layout, Cursor c, String[] from, int[] to)
{
super(context, layout, c, from, to, 0);
// ...
}
public View newView(Context context, Cursor cursor, ViewGroup parent)
{
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View retView = inflater.inflate(R.layout.lv_name_photo, parent, false);
RowViewHolder holder = new RowViewHolder();
holder.tvOne = (TextView) retView.findViewById(R.id.name);
holder.tvTwo = (TextView) retView.findViewById(R.id.txt_number);
holder.tvOne.setOnClickListener(tvOneLapOnClickListener);
retView.setTag(holder);
return retView;
}
#Override
public void bindView(View v, final Context context, Cursor c)
{
// ...
}
#SuppressWarnings("unchecked")
#Override
public View getView(final int position, View convertView, ViewGroup parent)
{
// ...
}
private OnClickListener tvOneLapOnClickListener = new OnClickListener() {
#Override
// When the tvOne button is clicked, execute this code
public void onClick(View v) {
// get the RowViewHolder
RowViewHolder holder = new RowViewHolder();
// Get the holder for the row
holder = (RowViewHolder) ((View) v.getParent()).getTag();
if (holder.tvOne.getVisibility() == View.INVISIBLE)
holder.tvOne.setVisibility(View.VISIBLE);
else
holder.tvOne.setVisibility(View.INVISIBLE);
}
};
}
protected void onListItemClick(ListView l, View v, int position, long id)
{
// ...
}
}

How to make clickable part of a textview in custom list view to open new activity in android

I have a custom listview with lazyadapter. I'm trying to make clickable part of the text view on the listview to open a new activity. But I'm stucked.
This is in LazyAdapter (I want to say that this is not an Activity. It is just LazyAdapter class):
private Activity activity;
private String[] urls;
private String[] tweets;
private String[] names;
private static LayoutInflater inflater = null;
public ImageLoader imageLoader;
public LazyAdapter(Activity a, String[] u, String[] n, String[] t) {
activity = a;
urls = u;
names = n;
tweets = t;
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader = new ImageLoader(activity.getApplicationContext());
}
public int getCount() {
return urls.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
if (convertView == null)
vi = inflater.inflate(R.layout.list_item, null);
TextView user = (TextView) vi.findViewById(R.id.textUser);
TextView tweet = (TextView) vi.findViewById(R.id.textTweet);
ImageView image = (ImageView) vi.findViewById(R.id.imageView);
user.setText(names[position]);
String[] checkHashtag= tweets[position].split(" ");
SpannableStringBuilder sb = new SpannableStringBuilder();
for(final String item: checkHashtag){
if(item.substring(0,1).matches("#")){
sb.append(item+" ");
sb.setSpan(new ClickableSpan() {
#Override
public void onClick(View view) {
Intent intent = new Intent(null, TweetActivity.class);
intent.putExtra("item", item);
Intent.startActivity(intent);
}
}, sb.length()-item.length(), sb.length(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} else sb.append(item+" ");
}
tweet.setText(sb);
if (tweets[position].toLowerCase().contains("http://")
|| tweets[position].toLowerCase().contains("https://")) {
String[] parts = tweets[position].split(" ");
for (String item : parts) {
URL url;
try {
url = new URL(item);
Pattern pattern = Pattern.compile(url.toString());
Linkify.addLinks(tweet, pattern, "http://");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
imageLoader.DisplayImage(urls[position], image);
return vi;
}
}
This is how I called LazyAdapter in Tweet Activity:
LazyAdapter adapter = new LazyAdapter(this, pic_urls, user_names, tweets);
setListAdapter(adapter);
But it is not working. Some problem in startActivity(intent) part.
Intent intent = new Intent(null, TweetActivity.class);
Here replace null by a
You must provide activity reference while starting another activity.
Write a.this instead of null in
Intnet intent = new Intent(null, TweetActivity.class);

Simplecursoradapter with Listview just mixed up while scrolling

Folks.
I've a problem with my simplecursorAdapter. Everything works perfectly except when scrolling the listview it just mixes up the Favorite icon for the rows which included in the custom layout and it just appears randomly while scrolling. Can you guide me what's wrong in my code?
Thanks in advance!
public class AlternateRowCursorAdapter extends SimpleCursorAdapter {
int layoutn;
Cursor localCursor, test;
Bitmap bitImg;
Context localContext;
Bitmap Avatar;
ImageView one, two, three, four, five;
LayoutInflater mInflater;
SQLiteDatabase mDb;
MyDbHelper mHelper;
public static final String TABLE_NAME = "MSGS";
public static final String COL_MsgID = "msgIdc";
public static final String COL_MsgCat = "msgCatC";
public static final String COL_MsgTit = "msgtitleC";
public static final String COL_MsgFavor = "msgFavorC";
public AlternateRowCursorAdapter (Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, R.layout.listtype, c, from, to);
this.localContext = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = super.getView(position, convertView, parent);
final Cursor cursbbn = getCursor();
if (row == null)
{
row = ((LayoutInflater) localContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.inflate(R.layout.listtype, null);
}
final String Title;
String SandID;
final String MsgID;
final String MsgFav;
Typeface tf = Typeface.createFromAsset(localContext.getAssets(),"fonts/khalaadsara.ttf");
Title = cursbbn.getString(2);
SandID = cursbbn.getString(1);
MsgID=cursbbn.getString(0);
MsgFav=cursbbn.getString(4);
TextView titler = (TextView) row.findViewById(R.id.Sandtit);
titler.setTypeface(tf);
titler.setText(Title);
one = (ImageView) row.findViewById(R.id.imageView5);
two = (ImageView) row.findViewById(R.id.imageView4);
three = (ImageView) row.findViewById(R.id.ImageView03);
four = (ImageView) row.findViewById(R.id.ImageView02);
five = (ImageView) row.findViewById(R.id.imageView1);
if(MsgFav.contentEquals("YES"))
{
one.setImageResource(R.drawable.favorpress);
}
return row;
}
}
Edit : Here is my code to refresh the values in Onresume event :
private void refreshvalues() {
mDb = mHelper.getWritableDatabase();
curs = mDb.query(MyDbHelper.TABLE_NAME, columns, null, null, null,
null, null,
null);
cursF = mDb.query(TABLE_NAME, columns, COL_MsgFavor + "=" + "?",
new String[] { "YES" }, null, null, COL_MsgTit + " ASC");
String[] headers = new String[] {MyDbHelper.COL_MsgTit ,MyDbHelper.COL_MsgID};
mAdapter = new AlternateRowCursorAdapter(this, R.layout.listtype, curs,
headers, new int[] { R.id.Sandtit});
fAdapter = new AlternateRowCursorAdapter(this, R.layout.listtype,
cursF, headers, new int[] { R.id.Sandtit });
mList.setAdapter(mAdapter);
fList.setAdapter(fAdapter);
curs.moveToFirst();
cursF.moveToFirst();
mAdapter.notifyDataSetChanged();
fAdapter.notifyDataSetChanged();
mList.invalidateViews();
fList.invalidateViews();
curs.requery();
cursF.requery();
}
First of all, you are customizing the ListView which needs to implement the custom adapter that extends any of the SimpleCustomAdapter, ArrayAdapter, and BaseAdapter.
Now, you get your listview messed up because, you are not holding the values in the views. You need to write a class ViewHolder that holds your views of the ListView in the same state, before it was scrolled. And Inside getView() method, you need to implement the else part of the if statement.
This is the efficient way to use ListView. Check below, how it can be implemented:
For example:
I made a class Task which contains the values from the database as:
static class Task {
int task_id;
String task_brief;
String task_priority;
String is_completed = "false";
Task(int tmp_task_id, String tmp_task_brief, String tmp_task_priority,
String tmp_task_is_completed) {
task_id = tmp_task_id;
task_brief = tmp_task_brief;
task_priority = tmp_task_priority;
is_completed = tmp_task_is_completed;
}
int get_task_id() {
return task_id;
}
String get_task_brief() {
return task_brief;
}
String get_task_priority() {
return task_priority;
}
String get_task_is_completed() {
return is_completed;
}
void set_task_is_completed(String tmp_task_is_completed) {
is_completed = tmp_task_is_completed;
}
}
Now, we create a class TaskViewHolder that holds the view:
static class TaskViewHolder {
TextView tv_task_brief;
ImageView iv_task_is_completed;
public TaskViewHolder(TextView tmp_tv_task_brief,
ImageView tmp_iv_task_is_completed) {
tv_task_brief = tmp_tv_task_brief;
iv_task_is_completed = tmp_iv_task_is_completed;
}
TextView get_tv_task_brief() {
return tv_task_brief;
}
ImageView get_iv_task_is_completed() {
return iv_task_is_completed;
}
}
And after that, implement custom adapter as below:
static class TaskAdapter extends ArrayAdapter<Task> {
LayoutInflater inflater;
public TaskAdapter(Context context, List<Task> tmp_al_task) {
super(context, R.layout.single_row_home,
R.id.textViewSingleRowHome, tmp_al_task);
inflater = LayoutInflater.from(context);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
Task task = (Task) this.getItem(position);
final ImageView imageView;
final TextView textView;
if (convertView == null) {
convertView = inflater.inflate(R.layout.single_row_home, null);
imageView = (ImageView) convertView
.findViewById(R.id.imageViewSingleRowHome);
textView = (TextView) convertView
.findViewById(R.id.textViewSingleRowHome);
convertView.setTag(new TaskViewHolder(textView, imageView));
} else {
TaskViewHolder viewHolder = (TaskViewHolder) convertView
.getTag();
imageView = viewHolder.get_iv_task_is_completed();
textView = viewHolder.get_tv_task_brief();
}
imageView.setTag(task);
textView.setText(task.get_task_brief());
if(task.get_task_priority().equals("High"))
textView.setTextColor(Color.RED);
else if(task.get_task_priority().equals("Medium"))
textView.setTextColor(Color.GREEN);
else
textView.setTextColor(Color.BLUE);
if (task.get_task_is_completed().equals("true")) {
imageView.setImageResource(R.drawable.action_cancel_icon);
textView.setPaintFlags(textView.getPaintFlags()
| Paint.STRIKE_THRU_TEXT_FLAG);
} else {
imageView.setImageResource(R.drawable.action_cancel_icon_2);
textView.setPaintFlags( textView.getPaintFlags() & (~ Paint.STRIKE_THRU_TEXT_FLAG));
}
imageView.setFocusable(false);
imageView.setFocusableInTouchMode(false);
imageView.setClickable(true);
imageView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Task task = (Task) imageView.getTag();
if (task.get_task_is_completed().equals("false")) {
imageView.setImageResource(R.drawable.action_cancel_icon);
ContentValues values = new ContentValues();
values.put("is_completed", "true");
database.update("task_info", values, "task_id=?",
new String[] { task.get_task_id() + "" });
values.clear();
textView.setPaintFlags(textView.getPaintFlags()
| Paint.STRIKE_THRU_TEXT_FLAG);
task.set_task_is_completed("true");
} else {
imageView.setImageResource(R.drawable.action_cancel_icon_2);
ContentValues values = new ContentValues();
values.put("is_completed", "false");
database.update("task_info", values, "task_id=?",
new String[] { task.get_task_id() + "" });
values.clear();
textView.setPaintFlags( textView.getPaintFlags() & (~ Paint.STRIKE_THRU_TEXT_FLAG));
task.set_task_is_completed("false");
}
}
});
return convertView;
}
}
Note: One important thing, if your ListView contains items that has click events, then that items should be set to view.setFocusable(false); view.setFocusableInTouchMode(false); and view.setClickable(true);. We need this because ListView takes the click event of any of the view as its own click event. Also, the view's click event should be separated from ListView's Click event.
ListView recycles list item Views. So make sure to always call one.setImageResource().
if (MsgFav.contentEquals("YES")) {
one.setImageResource(R.drawable.favorpress);
} else {
one.setImageResource(R.drawable.default_drawable_as_specified_in_layout);
}

Categories

Resources