CustomListViewAdapter - Button click to affect TextView outside of ListView - android

I have a layout which consist of a ListView and a TextView.
On the ListView items, it has one Button. On the Button's onClickListener, is it able to change the text of the TextView that is on the parent layout?
I have set the Button's onClickListener but have not been able to find a way to let the Button change the TextView properties etc.
Thanks! :)
Layout:

// try this way,hope this will help you..
**XML** code
**activity**
<?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:padding="5dp"
android:orientation="vertical" >
<TextView
android:id="#+id/txtChnageTextColor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:text="Android Demo Text For TextView"/>
<ListView
android:id="#+id/lstChangeTextColor"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="5dp"
android:layout_weight="1"/>
</LinearLayout>
**list_item**
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<TextView
android:id="#+id/txtColor"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="16sp"/>
<Button
android:id="#+id/btnSet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Set"/>
</LinearLayout>
**ACTIVITY** code
**MyActivity**
public class MyActivity extends Activity{
private ListView lstChangeTextColor;
private TextView txtChnageTextColor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);
lstChangeTextColor = (ListView) findViewById(R.id.lstChangeTextColor);
txtChnageTextColor = (TextView) findViewById(R.id.txtChnageTextColor);
ArrayList<HashMap<String,String>> listItem = new ArrayList<HashMap<String,String>>();
HashMap<String,String> map1 = new HashMap<String, String>();
map1.put("name", "Red");
map1.put("value", "#FF0000");
HashMap<String,String> map2 = new HashMap<String, String>();
map2.put("name", "Orange");
map2.put("value", "#FFA500");
HashMap<String,String> map3 = new HashMap<String, String>();
map3.put("name", "Yellow");
map3.put("value", "#FFFF00");
HashMap<String,String> map4 = new HashMap<String, String>();
map4.put("name", "Lime");
map4.put("value", "#00FF00");
HashMap<String,String> map5 = new HashMap<String, String>();
map5.put("name", "Blue");
map5.put("value", "#0000FF");
listItem.add(map1);
listItem.add(map2);
listItem.add(map3);
listItem.add(map4);
listItem.add(map5);
lstChangeTextColor.setAdapter(new ListAdapter(this,listItem));
}
class ListAdapter extends BaseAdapter{
private ArrayList<HashMap<String,String>> listItem;
private Context context;
public ListAdapter (Context context,ArrayList<HashMap<String,String>> listItem) {
this.listItem = listItem;
this.context = context;
}
#Override
public int getCount() {
return listItem.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public Object getItem(int position) {
return listItem.get(position);
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView==null) {
holder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.list_item,null,false);
holder.txtColor = (TextView) convertView.findViewById(R.id.txtColor);
holder.btnSet = (Button) convertView.findViewById(R.id.btnSet);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
holder.txtColor.setText(listItem.get(position).get("name"));
holder.btnSet.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
runOnUiThread(new Runnable() {
#Override
public void run() {
txtChnageTextColor.setTextColor(Color.parseColor(listItem.get(position).get("value")));
}
});
}
});
return convertView;
}
}
class ViewHolder{
Button btnSet;
TextView txtColor;
}
}

Related

Having troubles adding 3 layouts to 1 listview

I have a ListView and custom adapter and trying to get my data to be displayed inside of the ListView. I have three layouts to show the data but not able to get the data to display. I am having the hardcoded text of GROCERY being populated in each row for the list view not the three layouts I want and their respected data.
CustomAdapter
public class CompleteEReceiptDisplay extends Activity implements AppCompatCallback {
private AppCompatDelegate delegate;
Toolbar mToolbar;
private ImageView menuBtn, backBtn;
ListView mFullReceiptLV;
List<EreceiptPojo> mainList = new ArrayList<>();
private LayoutInflater mInflater;
private RelativeLayout mFullItemLine;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Show Toolbar without extending AppCompatActivity
delegate = AppCompatDelegate.create(this, this);
delegate.onCreate(savedInstanceState);
delegate.setContentView(R.layout.complete_ereceipt_display);
delegate.setSupportActionBar(mToolbar);
mFullReceiptLV = (ListView) findViewById(R.id.fullEReceiptListView);
menuBtn = (ImageView) findViewById(R.id.menuBtn);
backBtn = (ImageView) findViewById(R.id.icnBackArrow);
menuBtn.setVisibility(View.GONE);
backBtn.setVisibility(View.VISIBLE);
backBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
parseList();
FullEReceiptAdapter mFullAdapter = new FullEReceiptAdapter(this);
mFullReceiptLV.setAdapter(mFullAdapter);
}
private void parseList() {
String itemCateg = "", itemPrice = "", itemDesc = "";
HashMap<String, List<HashMap<String, String>>> mHashMap = new HashMap<>();
List<LineDetail> mLineDetailList = MainActivity.mCompleteReceiptData.getLineDetailList().getLineDetail();
for (int i = 0; i < mLineDetailList.size(); i++) {
LineDetail lineDetail = mLineDetailList.get(i);
itemPrice = lineDetail.getPrice();
List<Item> itemList = lineDetail.getCustomAttributes().getItem();
for (int j = 0; j < itemList.size(); j++) {
Item it = itemList.get(j);
if (it.getKey().equalsIgnoreCase("PrintCategory")) {
itemCateg = it.getValue();
} else if (it.getKey().equalsIgnoreCase("ItemDescription")) {
itemDesc = it.getValue();
}
}
HashMap<String, String> hm = new HashMap<>();
hm.put(itemDesc, itemPrice);
if (mHashMap.containsKey(itemCateg)) {
mHashMap.get(itemCateg).add(hm);
} else {
List<HashMap<String, String>> mMap = new ArrayList<>();
mMap.add(hm);
mHashMap.put(itemCateg, mMap);
}
}
for (Map.Entry<String, List<HashMap<String, String>>> entry : mHashMap.entrySet()) {
itemCateg = entry.getKey();
double mDouble = 0.00;
EreceiptPojo ereceiptPojo = new EreceiptPojo();
ereceiptPojo.setItemName(itemCateg);
ereceiptPojo.setCategory(true);
ereceiptPojo.setSubTotal(false);
mainList.add(ereceiptPojo);
List<HashMap<String, String>> dummyList = entry.getValue();
for (int i = 0; i < dummyList.size(); i++) {
HashMap<String, String> hm1 = new HashMap<>();
hm1 = dummyList.get(i);
for (Map.Entry<String, String> entry1 : hm1.entrySet()) {
EreceiptPojo ereceiptPojo1 = new EreceiptPojo();
ereceiptPojo.setItemName(entry1.getKey());
ereceiptPojo1.setItemPrice(entry1.getValue());
ereceiptPojo1.setCategory(false);
ereceiptPojo1.setSubTotal(false);
mainList.add(ereceiptPojo1);
mDouble = mDouble + Double.parseDouble(entry1.getValue());
}
}
EreceiptPojo mEreceiptPojo = new EreceiptPojo();
mEreceiptPojo.setItemPrice(String.valueOf(mDouble));
mEreceiptPojo.setCategory(false);
mEreceiptPojo.setSubTotal(true);
mainList.add(mEreceiptPojo);
}
}
#Override
public void onSupportActionModeStarted(ActionMode mode) {
}
#Override
public void onSupportActionModeFinished(ActionMode mode) {
}
#Nullable
#Override
public ActionMode onWindowStartingSupportActionMode(ActionMode.Callback callback) {
return null;
}
public class FullEReceiptAdapter extends BaseAdapter {
public static final int TYPE_ITEM = 0;
public static final int TYPE_CATEGORY = 1;
public static final int TYPE_ITEM_NAME = 2;
public static final int TYPE_PRICE = 3;
public FullEReceiptAdapter(Context context) {
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return mainList.size();
}
#Override
public Object getItem(int position) {
return mainList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getViewTypeCount() {
return 2;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
EreceiptPojo obj = mainList.get(position);
ViewHolder holder = null;
int layout_type = getItemViewType(position);
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.full_receipt_category_header, parent, false);
} else {
holder = (ViewHolder) convertView.getTag();
}
if (obj.isCategory() == true) {
holder = new ViewHolder();
holder.mHeaderView = (LinearLayout) convertView.findViewById(R.id.full_receipt_category_header_layout);
}
if (obj.isSubTotal() == true) {
holder = new ViewHolder();
holder.mLineItemsTotalPrice = (LinearLayout) convertView.findViewById(R.id.subTotalView);
}
if(obj.getItemName().length() > 0 && obj.getItemPrice().length() > 0) {
holder = new ViewHolder();
holder.mLineItemName = (RelativeLayout) convertView.findViewById(R.id.full_receipt_item_line);
}
return convertView;
}
}
public static class ViewHolder {
public LinearLayout mHeaderView;
public TextView mLineItemName;
public TextView mLineItemPrice;
public LinearLayout mLineItemsTotalPrice;
}
}
Three layouts I am tryign to attach to the adapter.
The first layout is the one that keeps repeating within the ListView.
<?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:id="#+id/full_receipt_category_header_layout">
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/full_receipt_category_header_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:paddingLeft="15dp"
android:text="GROCERY"
android:textAllCaps="true"
android:textColor="#color/colorBlack"
android:textSize="22dp"
android:textStyle="bold" />
</LinearLayout>
<?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="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/txtLineItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="CUB SPLT TOP WHEAT"
android:textSize="16sp"/>
<TextView
android:id="#+id/txtLineItemPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="$1.70*"
android:layout_alignParentRight="true"/>
</RelativeLayout>
<?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="vertical"
android:id="#+id/subTotalView">
<View
android:layout_width="50dp"
android:layout_height="1dp"
android:layout_marginTop="5dp"
android:background="#color/colorGrey"
android:layout_gravity="right"/>
<TextView
android:id="#+id/txtCategoryTotalPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="7dp"
android:text="$5.70"
android:textColor="#color/colorBlack"
android:layout_gravity="right"/>
</LinearLayout>
The layout that contains the ListView
<?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="vertical">
<include
android:id="#+id/app_bar"
layout="#layout/app_bar" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/bg_receipt"
android:padding="10dp">
<ImageView
android:id="#+id/bannerReceiptLogo"
android:layout_width="170dp"
android:layout_height="75dp"
android:background="#drawable/img_logo_receipt_cub"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"/>
<TextView
android:id="#+id/bannerAddressHeader"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="#string/storeHeader"
android:layout_below="#id/bannerReceiptLogo"
android:layout_marginTop="10dp"
android:textAlignment="center"
android:layout_centerHorizontal="true"
android:textSize="18sp"/>
<ListView
android:id="#+id/fullEReceiptListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/bannerAddressHeader"
android:layout_marginTop="10dp"
android:layout_marginBottom="5dp">
</ListView>
</RelativeLayout>
</LinearLayout>
I was able to get this working as I had to inflate each layout inside my adapter for each position within the view. The chances are in the getView().
#Override
public View getView(int position, View convertView, ViewGroup parent) {
EreceiptPojo obj = mainList.get(position);
TaxDetail taxDetail = new TaxDetail();
ViewHolder holder = null;
if (obj.isCategory()) {
convertView = mInflater.inflate(R.layout.full_receipt_category_header, parent, false);
TextView mCat = (TextView) convertView.findViewById(R.id.full_receipt_category_header_text);
mCat.setText(obj.getItemName());
}
else if (obj.isSubTotal()) {
convertView = mInflater.inflate(R.layout.full_receipt_category_total, parent, false);
TextView subTotal = (TextView) convertView.findViewById(R.id.txtCategoryTotalPrice);
subTotal.setText(obj.getItemPrice());
}
else if(!obj.isSubTotal() && !obj.isCategory()){
convertView = mInflater.inflate(R.layout.full_receipt_item_line, parent, false);
TextView itemName = (TextView) convertView.findViewById(R.id.txtLineItem);
TextView itemPrice = (TextView) convertView.findViewById(R.id.txtLineItemPrice);
itemName.setText(obj.getItemName());
itemPrice.setText(obj.getItemPrice());
} else {
convertView = mInflater.inflate(R.layout.tax_layout, parent, false);
TextView mFinalSubtotal = (TextView) convertView.findViewById(R.id.txtSubTotalFinal);
TextView mTotalTax = (TextView) convertView.findViewById(R.id.txtTaxTotal);
TextView mPurchaseTotal = (TextView) convertView.findViewById(R.id.txtCompleteTotalNumber);
for(int i = 0; i < obj.getItemPrice().length(); i++) {
String subTotalFinal = obj.setItemPrice(i);
}

Refresh ListView using Custom Adapter in Android

I am using Custom Adapter for ListView. Each ListView item contains ImageButton which will delete that Item. Now, I want to refresh full ListView when anyone click on ImageButton. How to do this ?
Or is there anyway to check ImageButton click on ListView onItemClickListener ? I have already tried notifyDataSetChanged in Custom Adapter but I can't find any changes.
Custom Item xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/lightish"
android:orientation="vertical"
android:padding="10dp" >
<ImageButton
android:id="#+id/imgDelete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginBottom="-20dp"
android:background="#android:color/transparent"
android:contentDescription="#string/app_name"
android:src="#drawable/ic_delete" />
<TextView
android:id="#+id/tvName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#color/black"
android:textSize="20sp" />
</LinearLayout>
Custom Adapter java :
public class MyAddressesAdapter extends BaseAdapter {
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater = null;
View vi;
HashMap<String, String> address;
public MyAddressesAdapter(Activity a,
ArrayList<HashMap<String, String>> arlData) {
activity = a;
data = arlData;
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, final View convertView, ViewGroup parent) {
vi = convertView;
if (convertView == null)
vi = inflater.inflate(R.layout.my_address_view, parent, false);
final TextView tvName = (TextView) vi.findViewById(R.id.tvName);
address = new HashMap<String, String>();
address = data.get(position);
tvName.setText(address.get("PersonName"));
return vi;
}
In main activity java :
myAddressesAdapter = new MyAddressesAdapter(
getActivity(), addressList);
lvMyAddresses.setAdapter(myAddressesAdapter);
put code in getview method in adapter
imageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//your code here
data.remove(position);
notifyDataSetChanged();
}
});

Assign onClick event for Button in list item of ListView

I have created a ListView that is populated from a database.Each row has a button to update the item value from the list and the database.I want to add onClick event for buttons used in item of ListView. How can I assign an OnClickListener for buttons for list items ?
addtooutlet.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:background="#ffffff">
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
addtooutlet_list_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffff"
android:padding="5dip" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="46dp"
android:background="#ffffff"
android:padding="5dip"
android:weightSum="100" >
<TextView
android:id="#+id/item_bname"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="25"
android:padding="2dp"
android:text="Hello"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#000000"
android:textSize="12dip" />
<TextView
android:id="#+id/item_bid"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="25"
android:padding="2dp"
android:text="Hello"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#000000"
android:textSize="12dip" />
<Button
android:id="#+id/item_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_alignTop="#+id/item_bname"
android:layout_marginRight="16dp"
android:layout_weight="50"
android:focusable="false"
android:focusableInTouchMode="false"
android:padding="2dp"
android:text="Join"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#000000"
android:textSize="12dip" />
</LinearLayout>
</LinearLayout>
AddTooutlet.java
public class AddToOutlet extends ListActivity {
SessionManager session;
String success, cus_id, bus_id;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.addtooutlet);
session = new SessionManager(getApplicationContext());
session.checkLoginback();
// get user data from session
HashMap<String, String> user = session.getUserDetails();
// ID
final String cus_id = user.get(SessionManager.KEY_ID);
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
ArrayList<NameValuePair> postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("cus_id", cus_id));
String response = null;
try {
response=LoginHttpClient.executeHttpPost("http://10.0.2.2/android_api/add_to_outlet.php",postParameters);
JSONObject json = new JSONObject(response);
JSONArray jArray = json.getJSONArray("customer");
for (int i = 0; i < jArray.length(); i++) {
HashMap<String, String> map = new HashMap<String, String>();
JSONObject json_data = jArray.getJSONObject(i);
map.put("bus_name", json_data.getString("bus_name"));
map.put("bus_id", json_data.getString("bus_id"));
success = json_data.getString("success");
mylist.add(map);
}
} catch (Exception e) {
Log.e("log_tag", "Error parsing data " + e.toString());
}
ListAdapter adapter = new SimpleAdapter(this, mylist,
R.layout.addtooutlet_list_item, new String[] { "bus_name",
"bus_id" },
new int[] { R.id.item_bname, R.id.item_bid });
setListAdapter(adapter);
}
public class Myadapter extends ArrayAdapter<String> {
private OnClickListener callback;
public Myadapter(Context context, int resource, int textViewResourceId,
String[] strings, OnClickListener callback) {
super(context, resource, textViewResourceId, strings);
this.callback = callback;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row = inflater.inflate(R.layout.addtooutlet_list_item, parent,
false);
Button buttonEdit = (Button) row.findViewById(R.id.item_button);
buttonEdit.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Log.i("xx", "Button pressed!");
}
});
return convertView;
}
private LayoutInflater getLayoutInflater() {
// TODO Auto-generated method stub
return null;
}
}
}
You have
View row = inflater.inflate(R.layout.addtooutlet_list_item, parent,
false);
But you return
return convertView;
Should be
View convertView = inflater.inflate(R.layout.addtooutlet_list_item, parent,
false);
And
Button buttonEdit = (Button) convertView.findViewById(R.id.item_button);
And
return convertView;
Edit:
As suggested in the comment by blackbelt. You are not using Custom ArrayAdapter
You probably meant
Myadapter adapter = new MyAdapter(ActivityName.this,R.layout.addtooutlet_list_item,mylist);
setListAdapter(adapter);
Then
ArrayList<HashMap<String,String> map;
LayoutInflater mInflater;
public Myadapter(Context context, int resource, int textViewResourceId,
ArrayLsit<HashMap<String,String> map, OnClickListener callback) {
super(context, resource, textViewResourceId, map);
this.map = map;
mInflater = LayoutInflater.from(context);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView ==null)
{
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.addtooutlet_list_item, parent,
false);
holder.tv1 = (TextView) convertView.findViewById(R.id.textView1);
holder.tv2 = (TextView) convertView.findViewById(R.id.textView2);
holder.b = (Button) convertView.findViewById(R.id.item_button);
convertView.setTaf(holder);
}else{
holder =(ViewHolder) convertView.getTag();
}
HashMap<String,String> hm = map.get(position);
holder.tv1.setText(hm.get(postion).get("bus_name").toString());
holder.tv2.setText(hm.get(postion).get("bus_id").toString());
holder.b.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Log.i("xx", "Button pressed!");
}
});
return convertView;
}
The ViewHodler
static class ViewHolder
{
Button b;
TextView tv1,tv2;
}
Now you should have a textview's in layout.addtooutlet_list_item.xml and update views in getView.
Also consider using a ViewHolder Pattern
http://developer.android.com/training/improving-layouts/smooth-scrolling.html

Android - Multiple selection in ListView

Okay, I am stuck whole day trying to get Checkbox added in listview. I have two part
If I click on any item in the listbox, it will load something (this part is already implemented).
There is a checkbox with each item. I want to be able to check any 10 or whatever number of items so that even if I scroll through the list, the selection will not get lost.
Can anyone please help me regarding that? One of the solution I checked is this solution, but I don't want to restructure whole code unless it is necessary.
MAINACTIVITY:
public class ShowList extends Activity{
static final String LIST_KEY_ID = "bookid";
static final String LIST_KEY_NAME = "bookname";
static final String LIST_KEY_WRITER = "writer";
ListView list;
MylibmanList adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_list);
setupActionBar();
mylibmandbhandler db = new mylibmandbhandler(this);
List<mylibman> allfld = db.getAllRecord();
db.close();
ArrayList<HashMap<String, String>> allbookList = new ArrayList<HashMap<String, String>>();
for (mylibman cn : allfld) {
HashMap<String, String> map = new HashMap<String, String>();
map.put(LIST_KEY_ID, Integer.toString(cn.getBookid()));
map.put(LIST_KEY_NAME, cn.getBookname());
map.put(LIST_KEY_WRITER, cn.getWriter());
allbookList.add(map);
}
list=(ListView)findViewById(R.id.list);
adapter=new MylibmanList(this, allbookList);
list.setAdapter(adapter);
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
batchid.clear();
HashMap<String, String> list_hashMap = (HashMap<String, String>) parent.getItemAtPosition(position);
String currlist = list_hashMap.get(LIST_KEY_ID);
Intent returnIntent = new Intent();
returnIntent.putExtra("bookid",currlist);
setResult(RESULT_OK,returnIntent );
finish();
}
});
ADAPTER CLASS:
public class MylibmanList extends BaseAdapter {
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater=null;
public MylibmanList(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
static class ViewHolder {
TextView title;
TextView artist;
TextView duration;
CheckBox check;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.listrow_row, null);
ViewHolder holder = new ViewHolder();
holder.title = (TextView)vi.findViewById(R.id.title);
holder.artist = (TextView)vi.findViewById(R.id.artist);
holder.duration = (TextView)vi.findViewById(R.id.duration);
holder.check = (CheckBox)vi.findViewById(R.id.check);
holder.check.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Log.d("test","t3"); // Don't know what to do
}
});
vi.setTag(holder);
holder.check.setTag(data.get(position));
HashMap<String, String> book = new HashMap<String, String>();
book = data.get(position);
ViewHolder holderfin = (ViewHolder) vi.getTag();
holderfin.title.setText(book.get(ShowList.LIST_KEY_NAME));
holderfin.artist.setText(book.get(ShowList.LIST_KEY_WRITER));
holderfin.duration.setText(book.get(ShowList.LIST_KEY_ID));
holderfin.check.setChecked(false);
return vi;
}
}
XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dip" >
<LinearLayout android:id="#+id/thumbnail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="3dip"
android:layout_alignParentLeft="true"
android:background="#drawable/image_bg"
android:layout_marginRight="5dip">
<!--
<ImageView
android:id="#+id/list_image"
android:contentDescription="#string/bookimage"
android:layout_width="50dip"
android:layout_height="50dip"/>
-->
</LinearLayout>
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/thumbnail"
android:layout_toRightOf="#+id/thumbnail"
android:focusableInTouchMode="false"
android:clickable="false"
android:focusable="false"
android:textColor="#040404"
android:typeface="sans"
android:textSize="18sp"
android:textStyle="bold"/>
<TextView
android:id="#+id/artist"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/title"
android:focusableInTouchMode="false"
android:clickable="false"
android:focusable="false"
android:textColor="#343434"
android:textSize="13sp"
android:layout_marginTop="1dip"
android:layout_toRightOf="#+id/thumbnail" />
<TextView
android:id="#+id/duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignTop="#id/title"
android:gravity="right"
android:focusableInTouchMode="false"
android:clickable="false"
android:focusable="false"
android:layout_marginRight="5dip"
android:textSize="12sp"
android:textColor="#10bcc9"
android:textStyle="bold"/>
<CheckBox
android:id="#+id/check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:focusable="false"
android:layout_marginRight="10dp" />
</RelativeLayout>
Basically, you can have a hashset that contains only the selected items. The code would look like this
public class MylibmanList extends BaseAdapter {
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater=null;
HashSet<String> selectedBooks = new HashSet<String>();
//This listener will be used on all your checkboxes, there's no need to
//create a listener for every checkbox.
CompoundButton.OnCheckedChangeListener checkChangedListener = new CompoundButton.OnCheckedChangeListener{
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
String bookDuration = (String) buttonView.getTag();
if(isChecked){
selectedBooks.add(bookDuration);
}else{
selectedBooks.remove(bookDuration);
}
}
}
public MylibmanList(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
static class ViewHolder {
TextView title;
TextView artist;
TextView duration;
CheckBox check;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView==null){
convertView = inflater.inflate(R.layout.listrow_row, null);
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.title);
holder.artist = (TextView) convertView.findViewById(R.id.artist);
holder.duration = (TextView) convertView.findViewById(R.id.duration);
holder.check = (CheckBox) convertView.findViewById(R.id.check);
holder.check.setOnCheckedChangeListener(checkChangedListener);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
HashMap<String, String> book = new HashMap<String, String>();
book = (HashMap<String, String>) getItem(position);
holder.check.setTag(book.get(ShowList.LIST_KEY_ID));
holder.title.setText(book.get(ShowList.LIST_KEY_NAME));
holder.artist.setText(book.get(ShowList.LIST_KEY_WRITER));
holder.duration.setText(book.get(ShowList.LIST_KEY_ID));
boolean bookSelected = false;
if(selectedBooks.contains(book.get(ShowList.LIST_KEY_ID))){
bookSelected = true;
}
holder.check.setChecked(bookSelected);
return convertView;
}
I've changed your getView abit. The viewHolder will now be created only once for each view (as it should). Also, if its not too much of a hustle, you should create a class for your book. Something like
Class Book{
String title;
String artist;
Long duration;
}

Android - ListView refresh/update from the Main Activity where it is called

I have an application that lists the values of a product by Variant, Unit, and Quantity.
I have an activity where the ListView is shown:
public class OrderForm extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_order_form);
ArrayList image_details = getListData();
final ListView lv1 = (ListView) findViewById(R.id.custom_list);
lv1.setAdapter(new CustomListAdapter(this, image_details));
}
private ArrayList getListData() {
ArrayList results = new ArrayList();
OrderDetailsClass orderData = new OrderDetailsClass();
return results;
}
public void onAddItem(View view){
ArrayList results = new ArrayList();
OrderDetailsClass orderData = new OrderDetailsClass();
orderData = new OrderDetailsClass();
orderData.setVariants("Flavored");
orderData.setUnit("cans");
orderData.setQuantity(1);
results.add(orderData);
//selectVariant();
//selectUnit();
//selectQuantity();
}
}
This is my CustomAdapter
public class CustomListAdapter extends BaseAdapter {
private ArrayList<OrderDetailsClass> listData;
private LayoutInflater layoutInflater;
public CustomListAdapter(Context context, ArrayList<OrderDetailsClass> listData) {
this.listData = listData;
layoutInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return listData.size();
}
#Override
public Object getItem(int position) {
return listData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.list_row_layout, null);
holder = new ViewHolder();
holder.variantView = (TextView) convertView.findViewById(R.id.variant);
holder.unitView = (TextView) convertView.findViewById(R.id.unit);
holder.quantityView = (TextView) convertView.findViewById(R.id.quantity);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.variantView.setText(listData.get(position).getVariants());
holder.unitView.setText("By, " + listData.get(position).getUnit());
holder.quantityView.setText(String.valueOf(listData.get(position).getQuantity()));
return convertView;
}
static class ViewHolder {
TextView variantView;
TextView unitView;
TextView quantityView;
}
public void updateResults(ArrayList<OrderDetailsClass> results) {
listData = results;
//Triggers the list update
notifyDataSetChanged();
}
}
This is list_row_layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!--
android:minHeight="50dp"
android:orientation="horizontal"
android:padding="5dip"
-->
<TextView
android:id="#+id/variant"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="variant" />
<TextView
android:id="#+id/unit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="unit" />
<TextView
android:id="#+id/quantity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="quantity" />
</RelativeLayout>
This is the activity_order_form
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ListView
android:id="#+id/custom_list"
android:layout_width="fill_parent"
android:layout_height="386dp"
android:dividerHeight="1dp" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:onClick="onAddItem"
android:text="Add" />
</RelativeLayout>
What I want to do is that when I press the onAddItem function, after the data has been added, the ListView will refresh and display the changes. So far, what I've seen is that notifyDataSetChanged() being used in the BaseAdapter class. I've tried it but it seems that notifyDataSetChanged() should be called within BaseAdapter, I want to be able to refresh from my OrderForm activity.
Any ideas?
Thanks.
Keep a reference to your CustomAdapter in OrderForm activity:
public class OrderForm extends Activity {
CustomListAdapter customListAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_order_form);
ArrayList image_details = getListData();
final ListView lv1 = (ListView) findViewById(R.id.custom_list);
customListAdapter = new CustomListAdapter(this, image_details);
lv1.setAdapter(customListAdapter);
}
Then you can call customAdapter.notifyDataSetChanged(). This is a public method on the adapter so you can call it from the activity just fine.

Categories

Resources