Android getView : Why getView not called? - android

I add two buttons (add and delete) to control the list view, when I delete an item, the item won't immediately disappear in the listview, only when I slide on the listview, the new item disappears. The getView() in my adapter won't be called after I delete an item unless I touch the screen or slide on the listview. can someone tell me why?
My xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/locationlist_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >"
<RelativeLayout
android:id="#+id/locationlisttitle_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:background="#ADD8E6">
<ImageView
android:id="#+id/iv_menu2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:src="#drawable/img_menu" />
<TextView
android:id="#+id/txtv_locationmanagetitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Manage Location List"
android:textSize="20sp" />
<ImageView
android:id="#+id/iv_addlocation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/txtv_locationmanagetitle"
android:src="#drawable/addlocation" />
<ImageView
android:id="#+id/iv_deletelocation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/iv_addlocation"
android:src="#drawable/deletelocation" />
</RelativeLayout>
<ListView
android:id="#+id/lv_locations"
android:layout_height="500dp"
android:layout_width="fill_parent" />
</LinearLayout>
My button click event handler
ivbtn_deleteLocation.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//remove selected items from the locationList
Collections.sort(listStr);
for (int i = listStr.size()-1; i >= 0; i--) {
Log.i("zhijianw", "remove"+listStr.get(i));
Log.i("zhijianw", "remove"+locationList.get(Integer.parseInt(listStr.get(i))).get("txtv_locationitem"));
String remLocation = locationList.get(Integer.parseInt(listStr.get(i))).get("txtv_locationitem").toString();
locationList.remove(Integer.parseInt(listStr.get(i)));
removeLocation(remLocation);
}
listStr = new ArrayList<String>();
locationsAdapter.notifyDataSetChanged();
}
});
My Adapter
public MyAdapter(Context context, List<HashMap<String, Object>> list, int resource, String[] from, int[] to) {
this.context = context;
this.list = list;
keyString = new String[from.length];
idValue = new int[to.length];
System.arraycopy(from, 0, keyString, 0, from.length);
System.arraycopy(to, 0, idValue, 0, to.length);
inflater = LayoutInflater.from(context);
init();
Log.i("zhijianw", "my adapter called");
}
public void init() {
isSelected = new HashMap<Integer, Boolean>();
for (int i = 0; i < list.size(); i++) {
isSelected.put(i, false);
}
}
#Override
public int getCount() {
Log.i("zhijianw", "get count called");
return list.size();
}
#Override
public Object getItem(int arg0) {
Log.i("zhijianw", "get item called");
return list.get(arg0);
}
#Override
public long getItemId(int arg0) {
return arg0;
}
#Override
public View getView(int position, View view, ViewGroup arg2) {
init();
Log.i("zhijianw", "get view called");
ViewHolder holder = null;
if (view == null) {
holder = new ViewHolder();
view = inflater.inflate(R.layout.location_item, null);
holder.tv = (TextView) view.findViewById(R.id.txtv_locationitem);
holder.cb = (CheckBox) view.findViewById(R.id.cb_locationitem);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
HashMap<String, Object> map = list.get(position);
if (map != null) {
itemString = (String) map.get(keyString[0]);
holder.tv.setText(itemString);
}
holder.cb.setChecked(isSelected.get(position));
return view;
}
}
Set listview adapter
lv_menu = (ListView) menu_view.findViewById(R.id.lv_menu);
lv_menu.setAdapter(new ArrayAdapter<String>(this, R.layout.menu_item, R.id.txtv_menuItem, menuChoices));

The locationsAdapter does not appear to be getting set to the same adapter used by lv_menu.setAdapter() so that locationsAdapter.notifyDataSetChanged() is not invalidating lv_menu. Try lv_menu.invalidate() directly in your onClick() function.
I personally reload my list adapters from scratch whenever deleting items, especially when CheckBox items are involved, in order to keep things from getting out of sync.

Please check that the parameter transfered to the inflater (in the getView method) refer to the same parameter which was used when the adapter was intiated. In the case that they are not the same the getView will not be called without any further notification.
Zohar

Related

Remove items from a Custom ListView (Android)

How do I create a neverending listview of list items with checkboxes that can be removed with a delete item button? The answer is below.
In order to create a neverending listview the first thing you need to have is a set of two runnables. These threads will update the array of data in your adapter.
final int itemsPerPage = 100;
ArrayList<HashMap<String,String>> listItems = new ArrayList<HashMap<String,String>>();
boolean loadingMore = false;
int item = 0;
//Since we cant update our UI from a thread this Runnable takes care of that!
public Runnable returnRes = new Runnable() {
#Override
public void run() {
//Loop thru the new items and add them to the adapter
if(groceries.getGroceries().size() > 0){
for(int i=0;i < listItems.size();i++) {
HashMap<String,String> grocery = listItems.get(i);
adapter.add(grocery);
}
//Update the Application title
setTitle("Grocery List with " + String.valueOf(groceries.getGroceries().size()) + " items");
//Tell to the adapter that changes have been made, this will cause the list to refresh
adapter.notifyDataSetChanged();
//Done loading more.
loadingMore = false;
}
}
};
//Runnable to load the items
public Runnable loadMoreListItems = new Runnable() {
#Override
public void run() {
//Set flag so we cant load new items 2 at the same time
loadingMore = true;
//Reset the array that holds the new items
listItems = new ArrayList<HashMap<String,String>>();
//Get 8 new listitems
for (int i = 0; i < itemsPerPage; i++) {
if (i < groceries.getGroceries().size()) {
listItems.add(groceries.getGroceries().get(i));
item++;
}
}
//Done! now continue on the UI thread
runOnUiThread(returnRes);
}
};
Then your onCreate() method should look something like this with an array passed to your adapter:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_grocery_list);
//add the footer before adding the adapter, else the footer will not load!
View footerView = ((LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.inflate(R.layout.activity_footer_view, null, false);
this.getListView().addFooterView(footerView);
adapter = new ListViewAdapter(this,groceries);
setListAdapter(adapter);
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
//Here is where the magic happens
this.getListView().setOnScrollListener(new OnScrollListener(){
//useless here, skip!
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {}
//dumdumdum
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
//what is the bottom iten that is visible
int lastInScreen = firstVisibleItem + visibleItemCount;
//is the bottom item visible & not loading more already ? Load more !
if((lastInScreen == totalItemCount) && !loadingMore && item < groceries.getGroceries().size()){
Thread thread = new Thread(null, loadMoreListItems);
thread.start();
}
}
});
}
You will also need a delete method to remove the items with checkboxes and a checkOff method as well. They look like this:
ArrayList<Integer> checkedBoxes = new ArrayList<Integer>();
ArrayList<HashMap<String,String>> checkedItems = new ArrayList<HashMap<String,String>>();
public void deleteItem(View view) {
if (checkedBoxes.size() > 1 || checkedBoxes.size() == 0) {
Toast.makeText(getApplicationContext(), "You can only delete one item at a time. Sorry :(", Toast.LENGTH_LONG).show();
return;
} else {
checkedItems.add(groceries.getGroceries().get(checkedBoxes.get(0)));
groceries.getGroceries().removeAll(checkedItems);
checkedBoxes.clear();
try {
groceries.serialize();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Intent intent = new Intent(getApplicationContext(),CreateGroceryList.class);
startActivity(intent);
}
}
public void checkOff(View view) {
CheckBox box = (CheckBox)view;
DataModel d = (DataModel)box.getTag();
if(!checkedBoxes.contains(d.index)) {
checkedBoxes.add(d.index);
} else {
checkedBoxes.remove((Integer)d.index);
}
}
In order to communicate with the adapter it is helpful to have a DataModel class that will model our information. My DataModel has an index variable to keep track of the selected item.
public class DataModel {
int index;
HashMap<String,String> data;
boolean selected;
public DataModel(int i) {
index = i;
data = new HashMap<String,String>();
selected = false;
}
public HashMap<String, String> getData() {
return data;
}
public void setData(HashMap<String, String> data) {
this.data = data;
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
}
Finally, here is the code for the BaseAdapter:
public class ListViewAdapter extends BaseAdapter {//To create an adapter we have to extend BaseAdapter instead of Activity, or whatever.
private ListActivity activity;
private View vi;
private ArrayList<DataModel> data;
private static LayoutInflater inflater=null;
public ListViewAdapter(ListActivity a, GroceryList g) {
activity = a;
data = new ArrayList<DataModel>();
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
groceries = g;
}
public void add(HashMap<String,String> a){
DataModel d = new DataModel(data.size());
d.setData(a);
d.setSelected(false);
data.add(d);
}
public ArrayList<DataModel> getData() {
return data;
}
public int getCount() { //get the number of elements in the listview
return data.size();
}
public Object getItem(int position) { //this method returns on Object by position
return position;
}
public long getItemId(int position) { //get item id by position
return position;
}
public View getView() {
return vi;
}
public View getView(int position, View convertView, ViewGroup parent) { //getView method is the method which populates the listview with our personalized rows
vi=convertView;
final ViewHolder holder = new ViewHolder();
if(convertView==null) {
vi = inflater.inflate(R.layout.custom_row_view, null);
//every item in listview uses xml "listview_row"'s design
holder.name = (CheckBox)vi.findViewById(R.id.name);
holder.price = (TextView)vi.findViewById(R.id.price); // You can enter anything you want, buttons, radiobuttons, images, etc.
holder.quantity = (TextView)vi.findViewById(R.id.quantity);
holder.name
.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
DataModel element = (DataModel) holder.name
.getTag();
element.setSelected(buttonView.isChecked());
}
});
vi.setTag(holder);
holder.name.setTag(data.get(position));
ViewHolder vholder = (ViewHolder) vi.getTag();
vholder.name.setChecked(data.get(position).isSelected());
HashMap<String, String> hash = new HashMap<String, String>(); //We need a HashMap to store our data for any item
hash = data.get(position).getData();
vholder.name.setText(hash.get("brand") + " " + hash.get("name")); //We personalize our row's items.
vholder.price.setText("$" + hash.get("price"));
vholder.quantity.setText("Quantity: " + hash.get("quantity"));
} else {
vi = convertView;
((ViewHolder) vi.getTag()).name.setTag(data.get(position));
}
if (holder.name == null) {
ViewHolder vholder = (ViewHolder) vi.getTag();
vholder.name.setChecked(data.get(position).isSelected());
HashMap<String, String> hash = new HashMap<String, String>(); //We need a HashMap to store our data for any item
hash = data.get(position).getData();
vholder.name.setText(hash.get("brand") + " " + hash.get("name")); //We personalize our row's items.
vholder.price.setText("$" + hash.get("price"));
vholder.quantity.setText("Quantity: " + hash.get("quantity"));
}
return vi;
}
}
class ViewHolder {
CheckBox name;
TextView price;
TextView quantity;
public CheckBox getName() {
return name;
}
public void setName(CheckBox name) {
this.name = name;
}
public TextView getPrice() {
return price;
}
public void setPrice(TextView price) {
this.price = price;
}
public TextView getQuantity() {
return quantity;
}
public void setQuantity(TextView quantity) {
this.quantity = quantity;
}
}
You also need a few xml files in your layout folder this is what they will look like:
You need a footerview that will tell your list when to load new items:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:gravity="center_horizontal"
android:padding="3dp"
android:layout_height="fill_parent">
<TextView
android:id="#id/android:empty"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:gravity="center"
android:padding="5dp"
android:text="Add more grocery items..."/>
A custom row view that is populated by your BaseAdapter:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<CheckBox
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="CheckBox"
android:focusable="false"
android:textSize="25dip"
android:onClick="checkOff"
/>
<TextView
android:id="#+id/quantity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="40dip"
android:text="Lastname"
android:textSize="15dip" />
<TextView
android:id="#+id/price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="40dip"
android:text="Lastname"
android:textSize="15dip" />
</LinearLayout>
And a parent view, mine is called create_grocery_list because I'm writing a grocery list editor: This one must contain a ListView with the proper id.
<?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" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="400dp" >
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" >
</ListView>
</LinearLayout>
<AbsoluteLayout
android:layout_width="match_parent"
android:layout_height="72dp" >
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="105dp"
android:layout_y="0dp"
android:onClick="deleteItem"
android:text="#string/deleteItem" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="8dp"
android:layout_y="0dp"
android:onClick="goToAddItemScreen"
android:text="#string/addItem" />
<Button
android:id="#+id/button3"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="221dp"
android:layout_y="0dp"
android:onClick="scanner"
android:text="#string/scanCode" />
</AbsoluteLayout>
</LinearLayout>
And that's about it... hope this helps anyone. It's the most complete tutorial you'll find.
I learned all this from this tutorial: http://www.vogella.com/articles/AndroidListView/article.html#androidlists_overview then added the two runnables to make a neverending grocery list :) have fun programming...

Minimize the listview row into a single line

I'm using listview to show the messages from the database..when i add a message it
takes all the string and showing on the listview..here is my xml file and java..
I need to get the message in a singline per rows with '...'. I researched for this question and i found,type
android:singleLine="true" in textview,but i don't know what they mean 'in textview'.becauz i'm using listview.please help.
<?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:background="#drawable/wave" >
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_below="#+id/SearchMessageExit"
android:focusableInTouchMode="true"
>
</ListView>
</LinearLayout>
message.java
public void detailsOfMessage(){
try{
Database_message info = new Database_message(this);
String data = info.getData();
info.close();
if(data.equals(""))
{
Toast.makeText(getApplicationContext(), "Empty Message", Toast.LENGTH_LONG).show();
}
StringTokenizer token = new StringTokenizer(data,"\t");
int rows = token.countTokens();
classes = new String[rows];
int i=0;
while (token.hasMoreTokens())
{
classes[i]=token.nextToken();
i++;
}
listView = (ListView) findViewById(R.id.list);
listView.setOnItemClickListener(this);
listView.setOnLongClickListener(this);
inAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,0);
listView.setAdapter(inAdapter);
for (int r = 0; r < classes.length; r++) {
inAdapter.add(classes[r]);
}
}catch(Exception e){
Toast.makeText(getApplicationContext(), "Empty Message", Toast.LENGTH_LONG).show();
}
}
you are using default layout android.R.layout.simple_list_item_1 for listview item. instead create one layout with textview with single line enable. and pass it to listview. and use custom array adapter for listview.
Do like this:
create list itemview XML
listview_item_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp">
<TextView android:id="#+id/txtTitle"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_vertical"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:textStyle="bold"
android:textSize="22dp"
android:textColor="#000000"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp" />
</LinearLayout>
One class like
Weather.java
public class Weather {
public String title;
public Weather(){
super();
}
public Weather(String title) {
super();
this.title = title;
}
}
and then create array adapter class
public class WeatherAdapter extends ArrayAdapter<Weather>{
Context context;
int layoutResourceId;
Weather data[] = null;
public WeatherAdapter(Context context, int layoutResourceId, Weather[] data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
WeatherHolder holder = null;
if(row == null)
{
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new WeatherHolder();
holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle);
row.setTag(holder);
}
else
{
holder = (WeatherHolder)row.getTag();
}
Weather weather = data[position];
holder.txtTitle.setText(weather.title);
return row;
}
static class WeatherHolder
{
TextView txtTitle;
}
}
And use like this in your activity:
Weather weather_data[] = new Weather[]
{
new Weather("Cloudy"),
new Weather("Showers"),
new Weather("Snow"),
new Weather("Storm"),
new Weather("Sunny")
};
WeatherAdapter adapter = new WeatherAdapter(this,
R.layout.listview_item_row, weather_data);
listView1.setAdapter(adapter);
Hope it Helps!!!
You need to implement a custom adapter for your ListView.
Along with that you should also implement, a custom_row.xml file for each row of your List View.
For Example:
1. Custom Adapter:
public class CustomAdapterListView extends BaseAdapter
{
private Activity activity;
private static LayoutInflater inflater=null;
private YOUR_DATA_TYPE data;
public CategoryDetailsCustomGridviewAdapter(Activity a, ArrayList<YOUR_DATA_TYPE> d)
{
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount()
{
// TODO Auto-generated method stub
return data.size();
}
#Override
public Object getItem(int position)
{
// TODO Auto-generated method stub
return position;
}
#Override
public long getItemId(int position)
{
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
// TODO Auto-generated method stub
View vi=convertView;
if(convertView==null)
{
vi = inflater.inflate(R.layout.YOUR_LISTVIEW_ROW_XML_FILE, null);
}
//Fetching the Data from ArrayList for each row.
TextView custom_row_tv = vi.findViewById(R.id.YOUR_TEXT_VIEW_ID)
YOUR_DATA_TYPE dataToBePopulated = new YOUR_DATA_TYPE;
custom_row_tv.setText(YOUR_DATA_TYPE.ToString());
dataToBePopulated = data.get(position);
return vi;
}
}
2. YOUR_LISTVIEW_ROW_XML_FILE.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/YOUR_TEXT_VIEW_ID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true" >
</TextView>
</RelativeLayout>
3. Setting up Your Custom Adapter:
Public Class YourClass extends Activity
{
onCreate(....)
{
setContentView(R.Layout.YOUR_LAYOUT_FILE);
ArrayList<YOUR_DATA_TYPE> data = new ArrayList<YOUR_DATA_TYPE>();
data.add(...) //Fetch your Data from Data source into this ArrayList.
ListView yourListView = (ListView)findViewById(R,id.YOUR_LISTVIEW_ID);
CustomAdapterListView adapter = new CustomAdapterListView (YourClass.this, data);
yourListView.setAdapter(adapter);
adapter.notifyDataSetChanged();
//YOUR OTHER FUNCTIONALITY......
}
//YOUR OTHER METHODS.....
....
....
}
This way you can simply implement a custom ListView with the Attribute of Single line attached to your TextView embedded within your ListView.
I hope this solves your problem.

Gridview click not working inside the Custom Listview

I'm using gridview inside a Listview, but I have a focusable problem.
I have set the width of the gridview, but I fill some items of gridview, on the left space of gridview (which is blank) means items not fill of gridview in listview. If I click on it, it does not perform a listitem click
As given in the image, I want to perform a listview item click if it is clicked anywhere in the list item. I want to get a listitem click.
But when I click on ListView item, that is, GridView then the ListItem click is not working...
public class History extends Activity {
String name, id, description, count, total;
ArrayList<String> TAG_ID = new ArrayList<String>();
ArrayList<String> TAG_COFFEESHOP_NAME = new ArrayList<String>();
ArrayList<String> TAG_COUNT = new ArrayList<String>();
ArrayList<String> TAG_TOTAL = new ArrayList<String>();
Context context;
JSONArray CoffeeUser = null;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listlayout);
ListView listView = (ListView) findViewById(R.id.listnew);
listView.setAdapter(new MyCustomAdapter());
listView.setTextFilterEnabled(true);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
public void onItemClick(AdapterView<?> paramAnonymousAdapterView, View paramAnonymousView, int paramAnonymousInt, long paramAnonymousLong)
{
Intent intent = new Intent();
intent.putExtra("coffeeshopid", ((TextView)paramAnonymousView.findViewById(R.id.hlcoffeeshopid)).getText() );
intent.setClass(getParent(), Stamps.class);
HistoryStack hisStack = (HistoryStack) getParent();
hisStack.push("Stamps", intent);
}
});
}
class MyCustomAdapter extends BaseAdapter {
Context ctx;
public MyCustomAdapter() {
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
SharedPreferences prfs = getSharedPreferences("GUID_FILE_NAME", Context.MODE_PRIVATE);
JSONObject json = jParser.methodhistory("http://api.com");
try {
// Getting Array of Employee
CoffeeUser = json.getJSONArray("CoffeeUser");
// Looping of List
for (int i = 0; i < CoffeeUser.length(); i++) {
JSONObject c = CoffeeUser.getJSONObject(i);
// Storing each json item in variable
id = c.getString("CS_Id");
name = c.getString("ShopName");
count = c.getString("totalstamps");
total = c.getString("threshholdcount");
// Adding all get values into array
if (name != "null") {
TAG_COFFEESHOP_NAME.add(name);
TAG_ID.add(id);
TAG_TOTAL.add(total);
TAG_COUNT.add(count);
}
}
}
catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public int getCount() {
return TAG_COFFEESHOP_NAME.size();
}
#Override
public Object getItem(int paramInt) {
return TAG_COFFEESHOP_NAME.get(paramInt);
}
#Override
public long getItemId(int paramInt) {
return paramInt;
}
public class MyCustomHolder {
public GridView localGrid;
public TextView CoffeeShopName,coffeeshopsdescription,coffeeshopid;
}
#Override
public View getView(int paramInt, View paramView,ViewGroup paramViewGroup) {
View localView = paramView;
MyCustomHolder holder = null;
if (localView == null) {
LayoutInflater inflater = (LayoutInflater) History.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
localView = inflater.inflate(R.layout.historylist, null);
holder = new MyCustomHolder();
holder.CoffeeShopName = (TextView) localView.findViewById(R.id.hlcoffeeshopname);
holder.coffeeshopid = (TextView) localView.findViewById(R.id.hlcoffeeshopid);
holder.localGrid = (GridView) localView.findViewById(R.id.gridViewdistorylist);
localView.setTag(holder);
}
else {
holder = (MyCustomHolder) localView.getTag();
}
holder.CoffeeShopName.setText(TAG_COFFEESHOP_NAME.get(paramInt));
holder.coffeeshopid.setText(TAG_ID.get(paramInt));
holder.localGrid.setAdapter(new GridAdapterA(History.this, TAG_TOTAL.get(paramInt), TAG_COUNT.get(paramInt)));
holder.localGrid.setFocusable(false);
holder.localGrid.setFocusableInTouchMode(false);
holder.CoffeeShopName.setFocusable(false);
holder.CoffeeShopName.setFocusableInTouchMode(false);
localView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.putExtra("coffeeshopid", ((TextView)v.findViewById(R.id.hlcoffeeshopid)).getText() );
intent.setClass(getParent(), Stamps.class);
HistoryStack hisStack = (HistoryStack) getParent();
hisStack.push("Stamps", intent);
}
});
return localView;
}
}
public class GridAdapterA extends BaseAdapter {
private Context context;
String total,count;
public GridAdapterA(Context context) {
this.context = context;
}
public GridAdapterA(Context context, String total, String count) {
// TODO Auto-generated constructor stub
this.context = context;
this.total = total;
this.count = count;
}
public boolean areAllItemsEnabled()
{
return false;
}
public boolean isEnabled(int position)
{
return false;
}
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
if (convertView == null) {
gridView = new View(context);
gridView = inflater.inflate(R.layout.customgrid_row, null);
gridView.setFocusable(false);
ImageView imageView = (ImageView) gridView.findViewById(R.id.grid_item_image);
imageView.setFocusable(false);
int i = 0;
if(count!="null")
i = Integer.parseInt(count);
if (position<i ) {
//imageView.setImageResource(R.drawable.ii);
// textView.setText(gridlist[position]);
}
else {
imageView.setImageResource(R.drawable.changedcup);
// textView.setText("");
}
}
else {
gridView = (View) convertView;
}
/*gridView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.putExtra("coffeeshopid", ((TextView)v.findViewById(R.id.hlcoffeeshopid)).getText() );
intent.setClass(getParent(), Stamps.class);
HistoryStack hisStack = (HistoryStack) getParent();
hisStack.push("Stamps", intent); }
});*/
return gridView;
}
#Override
public int getCount() {
int j=0;
if(total!="null"){
j = Integer.parseInt(total);
}
return j;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
}
}
historylist
<?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:background="#drawable/list_selector"
android:orientation="horizontal"
android:padding="5dip" >
<LinearLayout
android:id="#+id/thumbnail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginRight="5dip"
android:background="#drawable/image_bg"
android:padding="3dip" >
<ImageView
android:id="#+id/list_image"
android:layout_width="50dip"
android:layout_height="50dip"
android:src="#drawable/rcup" />
</LinearLayout>
<!-- hlcoffeeshopname Of Song -->
<TextView
android:id="#+id/hlcoffeeshopname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/thumbnail"
android:layout_toRightOf="#+id/thumbnail"
android:text="Rihanna Love the way lie"
android:textColor="#040404"
android:textSize="20dip"
android:textStyle="bold"
android:typeface="sans" />
<TextView
android:id="#+id/hlcoffeeshopid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
/>
<GridView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridViewdistorylist"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_below="#+id/hlcoffeeshopname"
android:layout_toRightOf="#+id/thumbnail"
android:columnWidth="20dp"
android:background="#null"
android:descendantFocusability="blocksDescendants"
android:focusable="false"
android:focusableInTouchMode="false"
android:numColumns="10"
android:stretchMode="none" >
</GridView>
</RelativeLayout>
New GetView
#Override
public View getView(int paramInt,
View paramView,
ViewGroup paramViewGroup) {
View localView = paramView;
MyCustomHolder holder = null;
if (localView == null) {
LayoutInflater inflater = (LayoutInflater) CopyOfHistory.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
localView = inflater.inflate(R.layout.copyhistorylist, null);
holder = new MyCustomHolder();
holder.coffeeShopName = (TextView) localView.findViewById(R.id.hlcoffeeshopname);
holder.coffeeshopid = (TextView) localView.findViewById(R.id.hlcoffeeshopid);
localView.setTag(holder);
}
else {
holder = (MyCustomHolder) localView.getTag();
}
holder.coffeeShopName.setText(TAG_COFFEESHOP_NAME.get(paramInt));
holder.coffeeshopid.setText(TAG_ID.get(paramInt));
int looplimit = Integer.parseInt(TAG_TOTAL.get(paramInt));
for (int i = 0; i < looplimit; i++) {
Log.e("loop", String.valueOf(looplimit));
ImageView imageView = new ImageView(CopyOfHistory.this);
if (i < Integer.parseInt(TAG_COUNT.get(paramInt))) {
imageView.setImageDrawable(getResources().getDrawable(R.drawable.ii));
} else {
imageView.setImageDrawable(getResources().getDrawable(R.drawable.iii));
}
RelativeLayout layout = (RelativeLayout) localView.findViewById(R.id.hlrlayout);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(30,30);
params.setMargins(i*40, 0, 0, 0);
imageView.setLayoutParams(params);
layout.addView(imageView);
//holder.relativeLayout = new RelativeLayout();
}
holder.coffeeShopName.setFocusable(false);
holder.coffeeShopName.setFocusableInTouchMode(false);
localView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.putExtra("coffeeshopid", ((TextView) v
.findViewById(R.id.hlcoffeeshopid)).getText());
intent.setClass(getParent(), Stamps.class);
HistoryStack hisStack = (HistoryStack) getParent();
hisStack.push("Stamps", intent);
}
});
return localView;
}
You might have solved it, but I have another solution that may help someone.
Use android:descendantFocusability="beforeDescendants" in the root layout of your list_cell XML.
Order to have lists within other lists. You must generate a custom view. If you want one the simple, consisting of a Java class and an XML file, then in the code you only have to instantiate it and add it to a linear layout.
Here I leave a small example.
XML
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical" >
<TextView
android:id="#+id/txtAltaPropinaTextoAyudaTipo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:gravity="center_vertical"
android:text="-"
android:textColor="#000000"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="#+id/txtListadoZonasNombreZona"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
android:layout_toLeftOf="#+id/txtAltaPropinaTextoAyudaTipo"
android:layout_toRightOf="#+id/txtAltaPropinaTextoAyudaTipo"
android:singleLine="true"
android:text="TextView"
android:textColor="#000000" />
</RelativeLayout>
Java code
public class CVTexto extends RelativeLayout {
public TextView txtTexto;
public int idCv;
public CVTexto(Context context) {
super(context);
// TODO Auto-generated constructor stub
IniciarCuadro();
}
public CVTexto(Context context, AttributeSet attrs) {
super(context, attrs);
IniciarCuadro();
}
public CVTexto(Context context, AttributeSet attrs, int defStyle) {
super( context, attrs, defStyle );
IniciarCuadro();
}
private void IniciarCuadro()
{
//Utilizamos el layout 'control_login' como interfaz del control
String infService = Context.LAYOUT_INFLATER_SERVICE;
LayoutInflater li =
(LayoutInflater)getContext().getSystemService(infService);
li.inflate(R.layout.ll_adapter_listado_zonas_asignadas_usuario, this, true);
AsignarElemetos();
//Obtenemoslas referencias a los distintos control
//Asociamos los eventos necesarios
// asignarEventos();
}
private void AsignarElemetos(){
txtTexto = (TextView)findViewById(R.id.txtListadoZonasNombreZona);
}
}
Add to linearlayout:
cvTextp objCV = new cvTexto(context);
LinearLayout.addView(objCv);
And delete views:
LinearLayout.removeallViews;
I got this answer by changing the grid layout to LinearLayout. I added items dynamically into linearLayout, and then my problem was solved.
I have done research on it and I get to know that inside a scrollable widget which uses an adapter you should not use any other widget which is scrollable which also uses an adapter such as gridview inside listview because of touch events complexity.
So I think you should move to another approach for this. In your case, you can add a linear layout and can add cup images dynamically into that layout by setting parameters. I hope this helped you.
I don't know how your below code is working, but if I would like handle each on-click listener of each then I would do something like below.
for (int i = 0; i < looplimit; i++) {
Log.e("loop", String.valueOf(looplimit));
ImageView imageView = new ImageView(CopyOfHistory.this);
if (i < Integer.parseInt(TAG_COUNT.get(paramInt))) {
imageView.setImageDrawable(getResources().getDrawable(R.drawable.ii));
}
else {
imageView.setImageDrawable(getResources().getDrawable(R.drawable.iii));
}
RelativeLayout layout = (RelativeLayout) localView.findViewById(R.id.hlrlayout);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(30,30);
params.setMargins(i*40, 0, 0, 0);
imageView.setLayoutParams(params);
layout.addView(imageView);
//holder.relativeLayout = new RelativeLayout();
// Handle your each on-click of dynamic added view while they added in getview() method
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Do what is necessary
}
});
}
I don't know how your below code is working, but if I would like handle each on-click listener of each then I would do something like below.
for (int i = 0; i < looplimit; i++) {
Log.e("loop", String.valueOf(looplimit));
ImageView imageView = new ImageView(CopyOfHistory.this);
if (i < Integer.parseInt(TAG_COUNT.get(paramInt))) {
imageView.setImageDrawable(getResources().getDrawable(R.drawable.ii));
}
else {
imageView.setImageDrawable(getResources().getDrawable(R.drawable.iii));
}
RelativeLayout layout = (RelativeLayout) localView.findViewById(R.id.hlrlayout);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(30,30);
params.setMargins(i*40, 0, 0, 0);
imageView.setLayoutParams(params);
layout.addView(imageView);
//holder.relativeLayout = new RelativeLayout();
// Handle your each on-click of dynamic added view while they added in getview() method
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Do what is necessary
}
});
}

Changing background color of list items in custom list view

I used the following code create a custom listview ....But the problem with this code it it is selecting only one item..but highlighting many items...i mean ..for example..if i have 8 items in the list..And i can see only 3 items(rest i have to scroll to see)..if i click the first item...it gets highlighted along with the fourth and the 7th item...
public class MainMenu extends Activity {
ListView lmenu;
View v1;
String s;
Class<?> ourclass;
View layout, row;
static int trantype;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.menulist);
Menu Menu_data[] = new Menu[] { new Menu("1.White"),
new Menu("2.Blue"), new Menu("3.Purple"), new Menu("4.Red"),
new Menu("5.Yellow"), new Menu("6.Black"), new Menu("6.Black"),
new Menu("6.Black"), new Menu("6.Black"), new Menu("6.Black"),
new Menu("6.Black"), new Menu("6.Black") };
MenuAdapter adapter = new MenuAdapter(this, R.layout.menutext,
Menu_data);
lmenu = (ListView) findViewById(R.id.mainmenu);
lmenu.setAdapter(adapter);
lmenu.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> ada, View v, int position,
long id) {
// TODO Auto-generated method stub
/*
* v.setBackgroundColor(Color.parseColor("#FCD5B5")); if (!(v1
* == null) && v1 != v)
* v1.setBackgroundColor(Color.parseColor("#EEEEEE")); v1 = v;
*/
Intent swipeit = new Intent(getBaseContext(), Swipeit.class);
trantype = position + 1;
startActivity(swipeit);
}
});
findViewById(R.id.BLogout).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
finish();
}
});
}
public class Menu {
public String title;
public Menu() {
super();
}
public Menu(String title) {
super();
this.title = title;
}
}
public class MenuAdapter extends ArrayAdapter<Menu> {
Context context;
int layoutResourceId;
Menu data[] = null;
LayoutInflater inflater;
boolean[] arrBgcolor;
private int activeHex, inactiveHex;
public MenuAdapter(Context context, int layoutResourceId, Menu[] data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
activeHex = Color.parseColor("#FCD5B5");
inactiveHex = Color.parseColor("#EEEEEE");
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
arrBgcolor = new boolean[13];
}
#Override
public View getView(final int position, final View convertView,
ViewGroup parent) {
try {
MenuHolder holder = null;
row = convertView;
// convertView.setBackgroundColor(Color.BLACK);
if (row == null) {
LayoutInflater inflater = ((Activity) context)
.getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new MenuHolder();
holder.txtTitle = (TextView) row.findViewById(R.id.tv1);
row.setTag(holder);
} else {
holder = (MenuHolder) row.getTag();
}
Menu Menu = data[position];
holder.txtTitle.setText(Menu.title);
holder.txtTitle.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
resetArrbg();
arrBgcolor[position] = true;
if (arrBgcolor[position]) {
row.setBackgroundColor(activeHex);
} else {
row.setBackgroundColor(inactiveHex);
}
notifyDataSetChanged();
}
});
} catch (Exception e) {
Toast.makeText(getApplicationContext(), String.valueOf(e),
Toast.LENGTH_LONG).show();
}
return row;
}
private void resetArrbg() {
for (int i = 0; i < arrBgcolor.length; i++) {
arrBgcolor[i] = false;
}
}
public class MenuHolder {
TextView txtTitle;
}
}
}
my xml containing list...
<include
android:id="#+id/header"
android:layout_alignParentTop="true"
layout="#layout/header" />
<RelativeLayout
android:id="#+id/Rlmain"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/header"
android:orientation="vertical" >
<TextView
android:id="#+id/TMain"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginBottom="8dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="8dp"
android:text="Main Menu"
android:textColor="#000000"
android:textSize="15dp" />
<View
android:id="#+id/Vtop"
android:layout_width="fill_parent"
android:layout_height="2dp"
android:layout_below="#+id/TMain"
android:background="#android:color/darker_gray" />
</RelativeLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#+id/Vbot"
android:layout_below="#+id/Rlmain"
android:orientation="vertical" >
<ListView
android:id="#+id/mainmenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#E0E0E0"
android:cacheColorHint="#00000000"
android:divider="#android:color/transparent"
android:dividerHeight="20dp" >
</ListView>
</RelativeLayout>
<View
android:id="#+id/Vbot"
android:layout_width="fill_parent"
android:layout_height="2dp"
android:layout_above="#+id/textView1"
android:background="#android:color/darker_gray" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="© India Transact Services Ltd."
android:textColor="#000000"
android:textSize="15dp" />
</RelativeLayout>
my xml for list....
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LLtv"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#EEEEEE"
android:cacheColorHint="#00000000" >
<TextView
android:id="#+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingBottom="12dp"
android:paddingTop="12dp"
android:textColor="#000000"
android:textSize="20dp" />
</LinearLayout>
Can please anyone help me and tell where i am going wrong?
What you want can't be achieved with your current setup. You need to implement a custom adapter where you have access to the getView() method. For reasons made clearer in the answer here, what you need to do is use some sort of data-container that will hold the status of an individual row using some indicator and then perform your action based on it's position on the container (which should correspond to its position on the listview)
for example, check out this re-write:
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
resetArrbg();
arrBgcolor[position] = true;
if (arrBgcolor[position]) {
v.setBackgroundColor(Color.parseColor("#FCD5B5"));
} else {
v.setBackgroundColor(Color.BLUE);
}
}
boolean[] arrBgcolor = new boolean[list.size()];
private void resetArrbg() {
for (int i = 0; i < arrBgcolor.length; i++) {
arrBgcolor[i] = false;
}
}
Does it make sense now why it can't work with the current set-up? The else part of the method, the part affecting the other views, can never take place because you don't have access to the other positions in the onListItemClick method, but you do in getView(). This is of course, unless you know of a way around this then, by all means, more power to you. all the same i don't think the v1 technique do you any good.
EDIT:
public class MainActivity extends Activity {
ListView lmenu;
View v1;
String s;
Class<?> ourclass;
View layout, row;
static int trantype;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.menulist);
Menu Menu_data[] = new Menu[] { new Menu("1.White"),
new Menu("2.Blue"), new Menu("3.Purple"), new Menu("4.Red"),
new Menu("5.Yellow"), new Menu("6.Black"), new Menu("6.Black"),
new Menu("6.Black"), new Menu("6.Black"), new Menu("6.Black"),
new Menu("6.Black"), new Menu("6.Black") };
MenuAdapter adapter = new MenuAdapter(this, R.layout.menutext, Menu_data);
lmenu = (ListView) findViewById(R.id.mainmenu);
lmenu.setAdapter(adapter);
}
public class Menu {
public String title;
public Menu() {
super();
}
public Menu(String title) {
super();
this.title = title;
}
}
public class MenuAdapter extends ArrayAdapter<Menu> {
Context context;
int layoutResourceId;
Menu data[];
LayoutInflater inflater;
boolean[] arrBgcolor;
private int activeHex, inactiveHex;
public MenuAdapter(Context context, int layoutResourceId, Menu[] data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
activeHex = Color.parseColor("#FCD5B5");
inactiveHex = Color.parseColor("#EEEEEE");
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
arrBgcolor = new boolean[data.length];
resetArrbg();
}
#Override
public View getView(final int position, final View convertView,
ViewGroup parent) {
final MenuHolder holder;
row = convertView;
// convertView.setBackgroundColor(Color.BLACK);
if (row == null) {
row = inflater.inflate(layoutResourceId, parent, false);
holder = new MenuHolder();
holder.txtTitle = (TextView) row.findViewById(R.id.tv1);
row.setTag(holder);
} else {
holder = (MenuHolder) row.getTag();
}
Menu Menu = data[position];
holder.txtTitle.setText(Menu.title);
if (arrBgcolor[position]) {
row.setBackgroundColor(activeHex);
} else {
row.setBackgroundColor(inactiveHex);
}
holder.txtTitle.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
resetArrbg();
arrBgcolor[position] = true;
notifyDataSetChanged();
}
});
return row;
}
private void resetArrbg() {
for (int i = 0; i < arrBgcolor.length; i++) {
arrBgcolor[i] = false;
}
}
public class MenuHolder {
TextView txtTitle;
}
}
}
This happens because of the way ListView reuses Views when populating the list. Lets say you see three rows of the list at any given time. You "highlight" the first row by setting the background color (like you do), and scroll down. When the first row leaves the screen, Android does something smart. Instead of creating a new View for, say, the fifth row, it reuses the View from row one. That's the View you changed the background color of, so row five now got the same background color. Only the data is changed.
As for how to implement a different background color on the selected row, and the selected row only, have a look at this answer. I do believe you got to implement a custom ListAdapter, at least if you're developing for API levels lower than 11.

ListView item can not clicked, not any other listeners getting called

I have made one custom ListView but it is not calling any onclick listener or context menu that I have registered.
Here is my custom adapter:
class AdapterContactsActivity extends BaseAdapter {
private Activity activity;
private ArrayList<HashMap<String, String>> rowdata;
private static LayoutInflater inflater = null;
public ArrayList<String> checkedContacts = new ArrayList<String>();
public AdapterContactsActivity(Activity a,
ArrayList<HashMap<String, String>> d) {
activity = a;
rowdata = d;
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return rowdata.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null)
convertView = inflater.inflate(R.layout.item_listview_contacts,
null);
final ViewHolder holder = new ViewHolder();
holder.txtTitle = (TextView) convertView.findViewById(R.id.textView1);
holder.chkBox = (CheckBox) convertView.findViewById(R.id.checkBox1);
final HashMap<String, String> row = rowdata.get(position);
// Setting all values in listview
holder.txtTitle.setText(row.get(EmsContactsActivity.KEY_TITLE));
final String contact_id = row.get(EmsContactsActivity.KEY_ID);
convertView.setTag(contact_id);
holder.txtTitle.setTag(contact_id);
if (checkedContacts.contains(contact_id))
holder.chkBox.setChecked(true);
else
holder.chkBox.setChecked(false);
holder.chkBox.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
if (!holder.chkBox.isChecked()
&& checkedContacts.contains(contact_id))
checkedContacts.remove(contact_id);
else {
checkedContacts.add(contact_id);
}
}
});
return convertView;
}
static class ViewHolder {
public TextView txtTitle;
public CheckBox chkBox;
}
}
Also my row's item view:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#android:color/black" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_toRightOf="#+id/checkBox1"
android:padding="5dp"
android:textAppearance="#android:style/TextAppearance.Large"
android:textColor="#android:color/white" />
<CheckBox
android:id="#+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:padding="5dp" />
</RelativeLayout>
Now I have added all contacts to the adapter but the on click of ListView item I can not even get logcat notification also so on click event I not called.
ListView Code :
Cursor allContacts = getAllContacts();
if (allContacts != null && allContacts.getCount() > 0) {
txtEmptyText.setVisibility(View.GONE);
registerForContextMenu(listViewContacts);
listViewContacts.setVisibility(View.VISIBLE);
listViewContacts.setFastScrollEnabled(true);
listViewContacts.setTextFilterEnabled(true);
listViewContacts.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listViewContacts.setBackgroundColor(Color.TRANSPARENT);
searchList = new ArrayList<HashMap<String, String>>();
searchList = getArrayListWithContacts(allContacts);
txtTotalContacts.setText("Displaying " + allContacts.getCount()
+ " contacts");
// Wrap your adapter within the SimpleSectionAdapter
searchAdapter = new AdapterContactsActivity(this, searchList);
// Set the adapter to your ListView
listViewContacts.setAdapter(searchAdapter);
listViewContacts.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View v,
int position, long arg3) {
// TODO Auto-generated method stub
Log.i("CLICKED", position + " clicked");
}
});
} else // No Contacts Found
{
String text = "<div>You don't have any contacts to display.<br /><br />"
+ "To add a contacts, <b>Menu</b> and touch:<br /><br />"
+ "• <b style='color:#FFFFFF;'>Accounts</b> to add or configure and account with contacts you can sync to the phone<br /><br />"
+ "• <b>New Contact</b> to create a new contact from scratch<br /><br />"
+ "• <b>Import/Export</b></div>";
txtEmptyText.setVisibility(View.VISIBLE);
listViewContacts.setVisibility(View.GONE);
txtEmptyText.setText(Html.fromHtml(text));
editSearchContacts.setEnabled(false);
}
Set the focusable property on the CheckBox to false:
<CheckBox
android:id="#+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:padding="5dp"
android:focusable="false" />
Also, you may want to inflate the row layout like this:
convertView = inflater.inflate(R.layout.item_listview_contacts, parent, false);
Your CheckBox has onClickListener so it can grab listview's click events.
Are you using OnItemClickListener on your ListView when you try to handle click events ( listView.setOnItemClickListener(...)) ?
If You are creating any custom row layout for the list item then.
Inside Row.xml
In Parent Linear Layout Or Relative LAyout you should put the one line
android:descendantFocusability="blocksDescendants"
This is working fine for me.

Categories

Resources