I'm having trouble displaying the right String from an ArrayList in my ListView.
My Array (m_aDataList) looks like this:
m_aDataList {ArrayList}
{...}0
m_cText = "R;21;9;River Street 2;12154;;1;.......
m_cTimeStamp = 1556553367492
m_nID = 7
m_nStatus = 0
m_nType = 10002
{...}1
....
This is how I'm currently trying to Display the ArrayList in my ListView:
ArrayAdapter<Message> tuAdapter;
MessageManager tu = new MessageManager();
ArrayList<Message> list = tu.getMessageData();
tuAdapter = new ArrayAdapter<Message>(this, android.R.layout.simple_list_item_1, list);
lvOrders.setAdapter(tuAdapter);
It technically works and adds something like this to my ListView:
de.telematik.testapp.entities.Message#232d9c76
But what I'm trying to do is, only show Messages where m_nType == 10002 and Display them like this in my ListView:
Order: 12154 (order number from m_cText)
Checking weither or not m_nType is = 10002 or 10000 shouldn't be the problem. But how do I get the order number out of the String m_cText and then display it in my ListView?
In any case, thanks for your help.
You are using a basic default list adapter, but you are passing it an array of objects (Message). In order to control what displays in the list, you will need to create your own custom adapter class, that extends (probably base adapter) one of the standard adapter classes. You will call it similarly to the way you pass your list to your simple list adapter. Here is a sample custom list adapter:
ClaimListAdapter.java
package com.mycompany.myapp.adapter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import com.mycompany.myapp.R;
import com.mycompany.myapp.ClaimListFragment;
import com.mycompany.myapp.model.ClaimItem;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.TextView;
public class ClaimListAdapter extends BaseAdapter {
private Context context;
private ArrayList<ClaimItem> claimItems;
ClaimListFragment fragment;
public ClaimListAdapter(ClaimListFragment fragment, Context context, ArrayList<ClaimItem> claimItems){
this.context = context;
this.claimItems = claimItems;
this.fragment = fragment;
}
#Override
public int getCount() {
return claimItems.size();
}
#Override
public Object getItem(int position) {
return claimItems.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#SuppressLint("InflateParams")
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// This method gets called for every item in the list when it is about to be displayed in the list
// This helps you get a reference to the layout of the list item
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.claim_list_item, null);
}
// If you have a button that you want to perform some function, such as delete, and then call
// a method back in the parent to update the items in the array, this is one way to do it
Button btnDelete = (Button) convertView.findViewById(R.id.claim_delete_in_list);
// Save the position of the item in the list, so, you know which item was clicked
btnDelete.setTag(position);
btnDelete.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Integer position = (Integer)v.getTag();
// Call this method which is back in the parent, which in this case is a fragment, but could be an Activity
fragment.deleteItemList(position);
}
});
btnDelete.setVisibility(View.GONE);
// Here you get a reference to the various TextViews in your layout
TextView txtTitle = (TextView) convertView.findViewById(R.id.claim_title);
TextView txtStatus = (TextView) convertView.findViewById(R.id.claim_status);
TextView txtDate = (TextView) convertView.findViewById(R.id.claim_date);
TextView txtDistance = (TextView) convertView.findViewById(R.id.claim_distance);
TextView txtAmount = (TextView) convertView.findViewById(R.id.claim_amount);
// Here you get the various strings out of your object for display
String claim_title = claimItems.get(position).getDocumentID();
if (claim_title == null) {
claim_title = "";
}
String claim_status = claimItems.get(position).getClaimStatus();
String claim_date = claimItems.get(position).getClaimDate();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Date date = null;
try {
date = (Date) dateFormat.parse(claim_date);
dateFormat = new SimpleDateFormat("M/d/yyyy");
String formattedDate = dateFormat.format(date);
txtDate.setText(formattedDate);
} catch (ParseException e) {
e.printStackTrace();
}
double total_miles = claimItems.get(position).getTotalMiles();
double total_amount = claimItems.get(position).getTotalAmount();
// Here you set the values in the TextView for display
txtTitle.setText(claim_title);
txtStatus.setText(claim_status);
txtDistance.setText("" + total_miles + "mi");
txtAmount.setText("$" + total_amount);
return convertView;
}
}
Alternatively, you could create a string array containing only the order numbers from your array of messages, and pass that array to your list adapter instead of the array of messages.
Related
I have an application that uses sqlite, it stores information about hardware store items and displays them in a ListView, this list view shows the name of the item, the price, the quantity, and the supplier. And each list item also has a Sell button and when I click the button it is supposed to subtract 1 from that specific item's quantity and update the database, but since the button is created in the CursorAdapter Im not sure how to access the database and update it.
This is my CursorAdapter:
package com.example.android.inventoryapp;
import android.content.Context;
import android.database.Cursor;
import android.support.v4.widget.CursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.android.inventoryapp.data.InventoryContract.InventoryEntry;
public class InventoryCursorAdapter extends CursorAdapter {
public InventoryCursorAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView itemNameView = view.findViewById(R.id.item_name);
TextView itemPriceView = view.findViewById(R.id.item_price);
TextView itemQuantityView = view.findViewById(R.id.item_quantity);
TextView itemSupplierView = view.findViewById(R.id.item_supplier);
ImageView sellButton = view.findViewById(R.id.sell_button);
int nameColumnIndex = cursor.getColumnIndex(InventoryEntry.COLUMN_ITEM_NAME);
int priceColumnIndex = cursor.getColumnIndex(InventoryEntry.COLUMN_ITEM_PRICE);
int quantityColumnIndex = cursor.getColumnIndex(InventoryEntry.COLUMN_ITEM_QUANTITY);
int supplierColumnIndex = cursor.getColumnIndex(InventoryEntry.COLUMN_ITEM_SUPPLIER);
int quantity = cursor.getInt(quantityColumnIndex);
String name = cursor.getString(nameColumnIndex);
String price = String.valueOf(cursor.getInt(priceColumnIndex)) + context.getString(R.string.currency_symbol);
String quantityStr = String.valueOf(quantity);
String supplier = cursor.getString(supplierColumnIndex);
itemNameView.setText(name);
itemPriceView.setText(price);
itemQuantityView.setText(quantityStr);
itemSupplierView.setText(supplier);
}
}
In your activity that holds the adapter reference, create an inner class something like:
public class MyClickListener {
public void handleClick(Item item) {
// access your DB here, {item} is available if you need the data
}
}
then when you create your adapter
myAdapter = new InventoryCursorAdapter(context, cursor, new MyClickListener());
save the reference to that click listener in your adapter.
then in the adapter's BindView method (if you need the item data to update the database, pass it through the click listener)
sellButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Item item = myItemSet.get(position);
myListener.handleClick(item);
}
});
In the following program, When I click on Add button in the options menu a dialog is opened wherein the user enters the data which is then shown in the ListView.
There are a number of problems with his code.
1) age.setText in the Custom Adapter causes the app to crash.Commenting out the age.settext line, it works well for the other two TextViews.
2) When i add data in the list using the dialog the second time, the list gets overwritten and no updation is done.
I want the list to be automatically updated when new data is entered rather than over writing it.
3) The data vanishes away when i restart the app. I want the data to be saved permanently.
Code for Custom Adapter is:
package com.example.sakshi.dialogsandmenus;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import org.w3c.dom.Text;
import java.util.ArrayList;
public class CustomAdapter extends BaseAdapter {
private Context context;
private ArrayList<Data> list;
private LayoutInflater mLayoutInflator;
public CustomAdapter(Context context, ArrayList list){
this.context=context;
this.list=list;
mLayoutInflator = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int position) {
return list.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = mLayoutInflator.inflate(R.layout.row,null);
TextView name = (TextView)convertView.findViewById(R.id.name);
TextView age = (TextView)convertView.findViewById(R.id.agedata);
TextView dob = (TextView)convertView.findViewById(R.id.dob);
name.setText(list.get(position).getName());
//age.setText(list.get(position).getAge());
dob.setText(list.get(position).getDate());
return convertView;
}
}
Code for Main Activity is:
package com.example.sakshi.dialogsandmenus;
import android.app.Dialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ListView;
import java.util.ArrayList;
import static android.R.id.list;
import static com.example.sakshi.dialogsandmenus.R.id.date;
public class MainActivity extends AppCompatActivity{
ListView listview;
ArrayList<Data> arrayList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listview = (ListView)findViewById(R.id.list_item);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.menu,menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id= item.getItemId();
if(id==R.id.add){
filldialog();
}
return super.onOptionsItemSelected(item);
}
public void filldialog(){
final Dialog dialog = new Dialog(MainActivity.this);
dialog.setCanceledOnTouchOutside(false);
dialog.setContentView(R.layout.dialog_layout);
dialog.show();
Button add = (Button)dialog.findViewById(R.id.additem);
final EditText getnamedata = (EditText)dialog.findViewById(R.id.name);
final EditText getagedata = (EditText)dialog.findViewById(R.id.age);
final DatePicker datePicker = (DatePicker)dialog.findViewById(date);
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String getname = getnamedata.getText().toString();
int getage = Integer.parseInt(getagedata.getText().toString());
int mm,y,d;
mm=datePicker.getMonth();
y=datePicker.getYear();
d=datePicker.getDayOfMonth();
String getdate = d+"/"+mm+"/"+y;
arrayList = new ArrayList<>();
Data data = new Data();
data.setName(getname);
data.setAge(getage);
data.setDate(getdate);
arrayList.add(data);
CustomAdapter customAdapter = new CustomAdapter(MainActivity.this,arrayList);
listview.setAdapter(customAdapter);
//customAdapter.notifyDataSetChanged();
dialog.dismiss();
}
});
}
}
1) you have to convert the value of age to String before setText
//age.setText(list.get(position).getAge());
age.setText(Integer.toString(list.get(position).getAge()));
2) Every time new Arraylist initilaization
intarrayList = new ArrayList<>();
ArrayList arrayList = new ArrayList<>();
public void filldialog(){
final Dialog dialog = new Dialog(MainActivity.this);
dialog.setCanceledOnTouchOutside(false);
dialog.setContentView(R.layout.dialog_layout);
dialog.show();
Button add = (Button)dialog.findViewById(R.id.additem);
final EditText getnamedata = (EditText)dialog.findViewById(R.id.name);
final EditText getagedata = (EditText)dialog.findViewById(R.id.age);
final DatePicker datePicker = (DatePicker)dialog.findViewById(date);
CustomAdapter customAdapter = new CustomAdapter(MainActivity.this,arrayList);
listview.setAdapter(customAdapter);
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String getname = getnamedata.getText().toString();
int getage = Integer.parseInt(getagedata.getText().toString());
int mm,y,d;
mm=datePicker.getMonth();
y=datePicker.getYear();
d=datePicker.getDayOfMonth();
String getdate = d+"/"+mm+"/"+y;
Data data = new Data();
data.setName(getname);
data.setAge(getage);
data.setDate(getdate);
arrayList.add(data);
customAdapter.notifyDataSetChanged();
dialog.dismiss();
}
});
enter code here
3) Use Sqlite or anyStorage Option for data saving
You are setting int value directly to setText of ageTextView. You need to convert int to String before you setting a text to TextView.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = mLayoutInflator.inflate(R.layout.row,null);
TextView name = (TextView)convertView.findViewById(R.id.name);
TextView age = (TextView)convertView.findViewById(R.id.agedata);
TextView dob = (TextView)convertView.findViewById(R.id.dob);
name.setText(list.get(position).getName());
//age.setText(list.get(position).getAge());
age.setText(String.valueOf(list.get(position).getAge())); // use this it will work
dob.setText(list.get(position).getDate());
return convertView;
}
}
Move these lines outside the onClickListener
arrayList = new ArrayList<>();
CustomAdapter customAdapter = new CustomAdapter(MainActivity.this,arrayList);
listview.setAdapter(customAdapter);
Because whenever you are clicking the button arraylist is initializing again.
This is the first question I am posting. Here is my question and below given is the debugged code from android studio.
Here, I have tried to extract the data by taking the data from the adapter into the mainActvity, but I failed as the app is crashing on Clicking the save button. Here the data is nothing but and object.
MainActivity :
import android.content.res.Resources;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
ArrayList<ListItem_Elements> testsList;
int n=5;//No. of tests
Button btn_save;
CustomAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView)findViewById(R.id.listView);
btn_save= (Button)findViewById(R.id.btn_save);
//CustomAdapter adapter;
Resources res=getResources();//Takes the resource permission required to show ListView
testsList= new ArrayList<ListItem_Elements>();
testsList = SetList();
adapter= new CustomAdapter(this, testsList, res);
listView.setAdapter(adapter);
btn_save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(testsList!=null)
saveValues();
}
});
}
public ArrayList<ListItem_Elements> SetList() {
/*Enter the Test names*/
ArrayList<ListItem_Elements>tests_Array= new ArrayList<ListItem_Elements>();
for(int i=0;i<5;i++) {
ListItem_Elements e = new ListItem_Elements();
e.setTest("XYZ");
e.setResult(null);
tests_Array.add(e);
}
return tests_Array;
}
ArrayList<ListItem_Elements>ar= new ArrayList<>();
public void saveValues() {
if(adapter.extractedArray!=null) {
ar = adapter.extractedArray;
Toast.makeText(MainActivity.this, ar.size(), Toast.LENGTH_SHORT).show();
}
}
}
--------------------------------------------------------------------------------
CustomAdapter :
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.TextView;
import java.util.ArrayList;
public class CustomAdapter extends BaseAdapter {
private Activity activity;
public static ArrayList<ListItem_Elements> extractedArray= new ArrayList<ListItem_Elements>();
private ArrayList<ListItem_Elements> array;
//Declaration of ArrayList which will be used to recieve the ArrayList that has to be putup into the ListView
private LayoutInflater inflater; //To Instantiates a layout XML file into its corresponding View
Resources res;
//protected String bridgeValue;
CustomAdapter(Activity a, ArrayList<ListItem_Elements> b, Resources resLocal) {
activity = a;
array= b;
res = resLocal;
//Initialization of inflater to link the layout of list items
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public CustomAdapter() {
}
#Override
public int getCount() {
return array.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
// keeping references for views we use view holder
public static class ViewHolder {
/*Declaration of elements of layout of list items in the class for future use of putting up
data onto the List View*/
TextView textView;
EditText editText;
}
#Override
//Here views were bound to a position
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
ViewHolder holder;
// if a view is null(which is for the first item) then create view
if (convertView == null) {
vi = inflater.inflate(R.layout.layout_items, null);
// Taking XML files that define the layout of items, and converting them into View objects.
holder = new ViewHolder();//Stores the elements of the layout of list items
/*Initializing the elements of the layout of list item*/
holder.textView = (TextView) vi.findViewById(R.id.textView);
holder.editText = (EditText) vi.findViewById(R.id.editText);
vi.setTag(holder);
//Stores the view(layout of list item) into vi
}
//else if it already exists, reuse it(for all the next items). Inflate is costly process.
else {
holder = (ViewHolder) vi.getTag();
//Restores the already exisiting view in the 'vi'
}
/*Setting the arrayList data onto the different elements of the layout of list item*/
try {
holder.textView.setText(array.get(position).getTest());
if(holder.editText.getText()!=null) {
ListItem_Elements obj = new ListItem_Elements();
obj.setTest(array.get(position).getTest());
obj.setResult(holder.editText.getText().toString());
extractedArray.add(position, obj);
}
}
catch (Exception e) {
e.getMessage();
}
return vi;//Returns the view stored in vi i.e contents of layout of list items
}
}
--------------------------------------------------------------------------------
public class ListItem_Elements {
String test;
String result;
ListItem_Elements() {
}
public String getTest() {
return test;
}
public void setTest(String test) {
this.test = test;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
}
You are missing some necessary code. EditText has a method called addTextChangedListener() which accepts a TextWatcher implementation. This implementation would be responsible for updating the data in the adapter.
final ListItem_Elements item = array.get(position);
holder.textView.setText(item.getTest());
holder.editText.setText(item.getResult());
holder.editText.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
item.setResult(s.toString());
}
// omitted empty impls for beforeTextChanged() and afterTextChanged(), you need to add them
});
Now, everytime the user updates the EditText, your adapter value will be updated. Then you just get the array values:
public void saveValues() {
// testLists in the activity and array in the adapter are references
// to the same list. So testLists already has the updated results
}
And take out this whole block of code:
holder.textView.setText(array.get(position).getTest());
if(holder.editText.getText()!=null) {
ListItem_Elements obj = new ListItem_Elements();
obj.setTest(array.get(position).getTest());
obj.setResult(holder.editText.getText().toString());
extractedArray.add(position, obj);
}
It doesn't do the right thing.
you are filling the listView with value from an ArrayList. Why you don't just get values from the your ArrayList ??
public void saveValues() {
if(tests_Array!=null) {
//and here you get values from your list
//by a simple for instruction
Toast.makeText(MainActivity.this, tests_Array.size(), Toast.LENGTH_SHORT).show();
}
}
Now i try to use adapter . But i dont understand how to set value from data .Becuase in friends = db.selectall ,value in friend have 3 value(fname,lname,nickname).So my question is How to set value(fname/lname/nickname OR one or the other) My code NOW look like this ::::
package com.example.sqlite;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.example.sqlite.db.FriendsDB;
import com.example.sqlite.entry.FriendEntry;
public class FriendsListActivity extends Activity {
private Context context;
private FriendsDB db;
private ArrayList<FriendEntry> friends;
private ArrayList<String> data;
private TextView hellotext;
private ListView hellolistview;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.friendlist_layout);
}
public void showAllList(){
//view matching
hellotext = (TextView) findViewById(R.id.hellotext);
hellolistview = (ListView) findViewById(R.id.hellolistview);
//select data
friends = db.selectAll();
if(friends.size()==0){
Toast.makeText(context,"You dont have any friend.",Toast.LENGTH_SHORT).show();
}else{
data = new ArrayList<String>();
for (int i = 1;i<=friends.size();i++){
// set value for data
**data.add("Your Name is "+friends["fname"]);<< I want to add data like this .How to correct**
}
}
}
private class adapter extends BaseAdapter{
private Holder holder;
#Override
//ดาต้ามีกี่แถว
public int getCount() {
// TODO Auto-generated method stub
return friends.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getView(int position, View view, ViewGroup parent) {
//create
if( view == null){
view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.item_layout,null);
holder = new Holder();
holder.title = (TextView) view.findViewById(R.id.item_title);
view.setTag(holder);
}else{
holder = (Holder) view.getTag();
}
//assign data / wait for data
return null;
}
private class Holder{
//view แต่ละตัวเก็บค่าอะไรบ้าง
public TextView title;
}
}
}
When you have data in Cursor and you want to display it in a ListView, you need to use a CursorAdapter.
You can either use the pre-defined SimpleCursorAdapter or if you want custom views, you can extend the CursorAdapter class.
Tutorial here: http://thinkandroid.wordpress.com/2010/01/11/custom-cursoradapters/
You are doing it allmost all right , but I suggest you to use an ArrayList of HashMap type instead of using Friends class.
This will lower your application burden.
ArrayList<HashMap<Object,String>> list=new ArrayList<HashMap<Object,String>>();
HashMap<Object,String> hm;
in your select all method
do{
hm=new HashMap<Object,String>();
hm.add(Key_Name,"retrieve the value from cursor here");
list.add(hm);
}while(c.movetonect());
return list;
in your activity
ArrayList<HashMap<Object,String>> list=new ArrayList<HashMap<Object,String>>();
list=db.selectAll();
HashMap<Object,String> hm;
for (int i=0;i<list.length;i++){
hm=list.getIndex(i); //retrieve all the vaalues here
}
use list adapters which accept list to populate the listview
I have defined onCheckedChanged for the checkbox in my listview.
When i click on the check box to check / uncheck it this function is getting invoked.
But when i setthe state of the check box from code like
check.setChecked(true);
the onCheckedChanged is not getting invoked.
Please help.
Adapter file :
package com.idg.project.adapters;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.TextView;
import com.idg.project.R;
import com.idg.project.activities.ScanListActivity;
import com.idg.project.activities.SearchResultActivity;
import com.idg.project.adapters.WishListAdapter.ViewHolder;
import com.idg.project.entity.ScannedProduct;
public class ScanListAdapter extends BaseAdapter {
private Context context;
private List<ScannedProduct> productList;
protected LayoutInflater mInflater;
Button showOrHideButton;
static public int count = 0;
String barcodeForSelectedRow;
String formatForSelectedRow;
OnItemClickListener rowListener;
Activity parentActivity;
boolean isWishList;
public ScanListAdapter(Context context, List<ScannedProduct> objects,
Button button, Activity parentActivity) {
super();
this.productList = objects;
this.context = context;
this.mInflater = LayoutInflater.from(context);
showOrHideButton = button;
this.parentActivity = parentActivity;
this.isWishList = isWishList;
}
public int getCount() {
return productList.size();
}
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
#Override
public void notifyDataSetChanged() {
// TODO Auto-generated method stub
super.notifyDataSetChanged();
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
final int pos = position;
Log.i("checkboxflag at : ", pos+"is"+(productList.get(pos).getCheckboxflag()));
Log.i("getview : fresh", "getview"+pos);
convertView = mInflater.inflate(R.layout.product_list_row, null);
holder = new ViewHolder();
holder.text1 = (TextView) convertView.findViewById(R.id.productid);
holder.text1.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(parentActivity,
SearchResultActivity.class);
intent.putExtra("barcode", productList.get(pos)
.getBarcode());
intent.putExtra("format", productList.get(pos).getFormat());
intent.putExtra("IsScan", false);
Log.i("", "" + productList.get(pos).getBarcode());
parentActivity.startActivity(intent);
Log.i("", "" + pos);
}
});
holder.text2 = (TextView) convertView.findViewById(R.id.price);
// holder.text2.setOnClickListener(listener);
holder.image = (ImageView) convertView
.findViewById(R.id.productimageid);
convertView.setTag(holder);
// holder.image.setOnClickListener(listener);
holder.text1.setText(productList.get(position).getTitle());
holder.text2.setText(productList.get(position).getPrice().toString());
if (productList.get(position).getSmallImage() != null) {
byte[] bb = (productList.get(position).getSmallImage());
holder.image.setImageBitmap(BitmapFactory.decodeByteArray(bb, 0,
bb.length));
} else {
holder.image.setImageBitmap(null);
holder.image.setBackgroundResource(R.drawable.highlight_disabled);
}
// holder.image.setImageBitmap(Utils.loadBitmap(productList.get(position).getSmallImage()));
final CheckBox check = (CheckBox) convertView
.findViewById(R.id.checkbox);
check.setClickable(true); // to remove anything carried over from prev convert view
if(productList.get(pos).getCheckboxflag()==1)
{
Log.i("CheckBox set checked",""+pos);
check.setChecked(true);
}
else{
Log.i("CheckBox set unchecked",""+pos);
check.setChecked(false);
}
setWishListItemsInScanList(pos, convertView);
check.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
Log.i("OnclickListener","Current Position"+pos);
if (check.isChecked()
&& productList.get(pos).getWishListFlag() == 0) {
if(check.isClickable()){
Log.i("CheckBox check",""+pos);
ScanListActivity.updateCheckBoxSelection(1, pos);
ScanListAdapter.count++;
}
} else if (!check.isChecked()
&& productList.get(pos).getWishListFlag() == 0){
if(check.isClickable()){
ScanListActivity.updateCheckBoxSelection(0, pos);
ScanListAdapter.count--;
Log.i("CheckBox UNcheck",""+pos);
}
}
if (ScanListAdapter.count == 0) {
// showOrHideButton.setClickable(false);
// showOrHideButton.setVisibility(View.GONE);
showOrHideButton.setEnabled(false);
} else {
// showOrHideButton.setVisibility(View.VISIBLE);
showOrHideButton.setEnabled(true);
}
}
});
return convertView;
}
private void setWishListItemsInScanList(int pos, View convertView) {
if (productList.get(pos).getWishListFlag() == 1) {
Log.i("CheckBox set checked from wish list",""+pos);
CheckBox check = (CheckBox) convertView.findViewById(R.id.checkbox);
check.setClickable(false);
check.setChecked(true);
}
}
static class ViewHolder {
TextView text1;
ImageView image;
TextView text2;
}
}
List activity file :
package com.idg.project.activities;
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.idg.project.R;
import com.idg.project.adapters.WishListAdapter;
import com.idg.project.adapters.ScanListAdapter;
import com.idg.project.entity.ScannedProduct;
import com.idg.project.services.ScannedProductDataAccessManager;
public class ScanListActivity extends BaseActivity {
static Button scanlist;
ScanListAdapter listAdapter;
static List<ScannedProduct> productList;
/* Notes for the Developer :
* For tracking the checked items Checkboxflag
* is maintained.
* Point1 : Select all will just set this flag in the local list and then call notifyDatachange of the adapter
* within adapter the check box is set or reset based on this flag for each row
*
* Point 2: When individual rows are selected , there is an onclick of the check box is invoked
* Here the Checkboxflag of the local list is set /unset . Also we need a way to knpw the select all button is
* to enabled or diabled. for that Count variable is updated here.
* Now Important point is these two actions shoulnt be taking place if the checkbox state change due to select all
* So there is a special check of isclickable in the onclicklistener
*
* Point 3: In scan list the items in the wish list are to be marked. This again needs special logic.
* This is done in the adapter code by checking all the rows whose wishListFlag is 1 and making it non clickable
*
* Important : Listview has the concept of ViewGroup and each view group is usually the rows fitting in the display screen
* so when we scroll, the viewGropu changes.
* Convertview is get reused for view groups. So need to careful undesired values that will be carried to next viewgroup*/
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.scan_list);
productList = new ArrayList<ScannedProduct>();
productList = getProductList();
for(int i=0;i<productList.size();i++){
Log.i("checkboxflag at : ", i+"is"+(productList.get(i).getCheckboxflag()));
}
final ListView lv = (ListView) findViewById(R.id.list);
scanlist = (Button) findViewById(R.id.addtowishlist);
scanlist.setEnabled(false);
listAdapter = new ScanListAdapter(this, productList, scanlist, this);
lv.setAdapter(listAdapter);
}
private List<ScannedProduct> getProductList() {
List<ScannedProduct> productList = new ArrayList<ScannedProduct>();
ScannedProductDataAccessManager productDataBaseManager = new ScannedProductDataAccessManager(
getApplicationContext());
String[] colList = { "title", "smallImage", "price" };
productList = productDataBaseManager.fetchAllProducts();
return productList;
}
static boolean selectFlag = false;
public void selectAll(View view) {
ListView listView = (ListView) findViewById(R.id.list);
view = findViewById(R.id.select_all);
if (selectFlag == false) {
for (int i = 0; i < listView.getAdapter().getCount(); i++) {
productList.get(i).setCheckboxflag(1);
}
view.setBackgroundResource(R.drawable.login_remme_dwn_btn);
selectFlag = true;
TextView text=(TextView) findViewById(R.id.select);
text.setText("Unselect All");
scanlist.setEnabled(true);
} else {
for (int i = 0; i < listView.getAdapter().getCount(); i++) {
productList.get(i).setCheckboxflag(0);
}
view.setBackgroundResource(R.drawable.login_remme_up_btn);
selectFlag = false;
TextView text=(TextView) findViewById(R.id.select);
text.setText("Select All");
scanlist.setEnabled(false);
}
((BaseAdapter)listView.getAdapter()).notifyDataSetChanged(); // we are only setting the flags in the list
// so need to notify adapter to reflect same on checkbox state
//listView.refreshDrawableState();
}
public void addToWishList(View view) {
ListView listView = (ListView) findViewById(R.id.list);
for (int i = 0; i < listView.getAdapter().getCount(); i++) {
ScannedProduct product = productList.get(i);
if (product.getWishListFlag() == 0 && product.getCheckboxflag()==1) {
product.setWishListFlag(1);
new ScannedProductDataAccessManager(getApplicationContext())
.updateProduct(product, "title",
new String[] { product.getTitle() });
product.setCheckboxflag(0);
//ScanListAdapter.count--;
}
Log.i("ScanList selected", product.getTitle());
}
Toast.makeText(getApplicationContext(),
"Added selected items to Wish List", Toast.LENGTH_SHORT).show();
scanlist.setEnabled(false);
((BaseAdapter)listView.getAdapter()).notifyDataSetChanged();
}
static public void updateCheckBoxSelection(int flag,int pos){ // when individual row check box is checked/ unchecked
// this fn is called from adapter to update the list
productList.get(pos).setCheckboxflag(flag);
}
}
Since your checkbox is inside listview, so you need to call notifyDataSetChanged method on your list's adapter to refresh it's contents.
update
instead of ((BaseAdapter)listView.getAdapter()).notifyDataSetChanged();, try calling listAdapter.notifyDataSetChanged();
I got the answer / bug in my code
i am not reusing convertview so its every time a new holder.
I am changing the flag of the checkbox and then assigning a statechange listener for the checkbox
thus its not getting invoked
when i changed the order to assign checkchangelistener before actually changing the state , its working as expected. The listener is getting called.
thanks all of you