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
}
});
}
Related
i have seen many answers and i changed my code accordingly. now i am stuck with my own problem.after running this adapter , i am getting one value from list1 and only two values from list2 where both have three values.the layouts are coming fine.i don't know what is causing it and i am also not that much familiar with arrayadapter. it will be a great help. thanks in advance.
public class AxisAdapter extends ArrayAdapter<String> {
private ArrayList<String> list1 = new ArrayList<String>();
private ArrayList<String> list2 = new ArrayList<String>();
private Context context;
private final int view1 = 0;
private final int view2 = 1;
public MyAdapter(Context context, ArrayList<String> records,ArrayList<String> records1) {
super(context, 0, records);
this.context = context;
list1=records;
list2=records1;
}
public int getViewTypeCount() {
return 2;
}
public int getItemViewType(int position) {
return (position == 0) ? view1 : view2;
}
#Override
public View getView(final int position, #Nullable View convertView, #NonNull ViewGroup parent) {
int viewType = getItemViewType(position);
switch (viewType) {
case view1: {
final String item = list1.get(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.abc_layout, parent, false);
}
final TextView list_Txt = (TextView) convertView.findViewById(R.id.txtDef);
Button list_But = (Button) convertView.findViewById(R.id.btnCall);
list_Txt.setText(item.replaceAll("[^A-Za-z]", " "));
list_But.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String number = item.replaceAll("[A-Za-z]", "");
Intent i = new Intent(Intent.ACTION_VIEW,
Uri.parse("tel:" + number));
context.startActivity(i);
}
});
}
break;
case view2: {
final String item = list2.get(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.url_layout, parent, false);
}
final TextView list_Txt = (TextView) convertView.findViewById(R.id.txtDetail);
Button list_But = (Button) convertView.findViewById(R.id.btnVisit);
list_Txt.setText(item.replaceAll("[^A-Za-z]", " "));
list_But.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String number = item.replaceAll("[A-Za-z]", "");
Intent i = new Intent(Intent.ACTION_VIEW,Uri.parse("tel:12345"));
context.startActivity(i);
}
});
}
break;
}
return convertView;
}
}
in my activity class
public class AnActivity extends AppCompatActivity {
Toolbar toolbar;
AxisAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_axis);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if(getSupportActionBar()!= null){
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
ListView list = (ListView) findViewById(R.id.axisList);
String[] ussd = getResources().getStringArray(R.array.axisCode);
String[] links = getResources().getStringArray(R.array.axisLink);
ArrayList<String> myData = new ArrayList<String>();
ArrayList<String> myLinks = new ArrayList<String>();
for(int i = 0; i<ussd.length;i++) {
myData.add(ussd[i]);
}
for(int i =0;i<links.length;i++){
myLinks.add(links[i]);
}
adapter = new AxisAdapter(this,myData,myLinks);
list.setAdapter(adapter);
//adapter= new AxisAdapter(this,myLinks);
//list.setAdapter(adapter);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home)
finish();
return super.onOptionsItemSelected(item);
}
}
and in my both layout class, there is one button and one text box.
<?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="match_parent"
android:orientation="horizontal"
android:padding="5dp"
android:background="#color/textboxColor">
<TextView
android:id="#+id/txtDef"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginLeft="2dp"
android:layout_weight="1"
android:fontFamily="#font/roboto_slab"
android:padding="5dp"
android:text="TextView"
android:textAppearance="#style/TextAppearance.AppCompat.Large"
android:textSize="20sp" />
<Button
android:id="#+id/btnCall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="2dp"
android:layout_weight="0"
android:fontFamily="#font/roboto_slab_bold"
android:text="Call"
android:theme="#style/PrimaryButton" />
</LinearLayout>
</LinearLayout>
another one:
<?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="match_parent"
android:orientation="horizontal"
android:padding="5dp"
android:background="#color/textboxColor">
<TextView
android:id="#+id/txtDetail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginLeft="2dp"
android:layout_weight="1"
android:fontFamily="#font/roboto_slab"
android:padding="5dp"
android:text="TextView"
android:textAppearance="#style/TextAppearance.AppCompat.Large"
android:textSize="20sp" />
<Button
android:id="#+id/btnVisit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="2dp"
android:layout_weight="0"
android:fontFamily="#font/roboto_slab_bold"
android:text="Visit"
android:theme="#style/PrimaryButton" />
</LinearLayout>
</LinearLayout>
Try to send some string like in below case a string to determine the type, what you are actually trying to switch between, in my case it was monthly,yearly and so on, based on that string you can use different views or maybe show alternative layouts easily.
public class incomeadapter extends ArrayAdapter {
private List<Incomemodel> getdatas;
private int resource;
String incometype;
private LayoutInflater inflater;
Context context;
public incomeadapter(Context context, int resource, List<Incomemodel> getdata, String type) {
super(context, resource, getdata);
this.context = context;
getdatas = getdata;
incometype = type;
this.resource = resource;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView t1, t2;
if (convertView == null) {
if (incometype.equals("monthly")) {
convertView = inflater.inflate(R.layout.incomemonthly_item, null);
t1 = (TextView) convertView.findViewById(R.id.text2);
t2 = (TextView) convertView.findViewById(R.id.text1);
t1.setText(getdatas.get(position).getMonths());
t2.setText(getdatas.get(position).getIncome());
}
if (incometype.equals("yearly")) {
convertView = inflater.inflate(R.layout.incomeyearly_item, null);
t1 = (TextView) convertView.findViewById(R.id.text2);
t2 = (TextView) convertView.findViewById(R.id.text1);
t1.setText(getdatas.get(position).getYear());
t2.setText(getdatas.get(position).getIncome());
}
}
return convertView;
}
}
PS. Try using recyclerview with multiple viewholders, that will make it easy i guess
Your concern:
i am getting one value from list1 and only two values from list2 where
both have three values
The problem you are facing lies in these places:
private final int view1 = 0;
private final int view2 = 1;
...
public int getItemViewType(int position) {
return (position == 0) ? view1 : view2;
}
And then you call getItemViewType method in the getView() method:
int viewType = getItemViewType(position);
The value of position ranges from 0 to the number of items in the list minus 1. So the getItemViewType() method always return 0 (view1) if position = 0, and return 1 (view2) if position = 1, 2, 3...
You then write:
switch (viewType) {
case view1: {
final String item = list1.get(position);
...
}
break;
case view2: {
final String item = list2.get(position);
...
}
break;
}
In the case view1, it is simply indicating the first item in your list with position = 0. There is only 1 item staying at position 0, so final String item = list1.get(position); is only called once, that is why it returns 1 value.
In the case view2, it is simply indicating the items at position 1, 2, 3... As you said there are 3 items in the list, the adapter will generate 3 items for the list view and case view2 will be equal to position 1 and 2. So final String item = list2.get(position); is called twice, that is why it returns 2 values.
I dont know what your next step would be because I don't understand what you expect.
Update: specific solution:
public class AxisAdapter extends ArrayAdapter<String> {
private ArrayList<String> list1;
private ArrayList<String> list2;
private Context context;
public AxisAdapter(Context context, ArrayList<String> records,ArrayList<String> records1) {
super(context, 0);
this.context = context;
list1=records;
list2=records1;
}
#Override
public int getCount() {
return list1.size() + list2.size();
}
public int getViewTypeCount() {
return 2;
}
#Override
public View getView(final int position, #Nullable View convertView, #NonNull ViewGroup parent) {
if (position < list1.size()) {
final String item = list1.get(position);
convertView = LayoutInflater.from(getContext()).inflate(R.layout.abc_layout, parent, false);
final TextView list_Txt = (TextView) convertView.findViewById(R.id.txtDef);
Button list_But = (Button) convertView.findViewById(R.id.btnCall);
list_Txt.setText(item.replaceAll("[A-Za-z]", ""));
list_But.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String number = item.replaceAll("[A-Za-z]", "");
Intent i = new Intent(Intent.ACTION_VIEW,
Uri.parse("tel:" + number));
context.startActivity(i);
}
});
}
else {
final String item = list2.get(position - list1.size());
convertView = LayoutInflater.from(getContext()).inflate(R.layout.url_layout, parent, false);
final TextView list_Txt = (TextView) convertView.findViewById(R.id.txtDetail);
Button list_But = (Button) convertView.findViewById(R.id.btnVisit);
list_Txt.setText(item.replaceAll("[A-Za-z]", ""));
list_But.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String number = item.replaceAll("[A-Za-z]", "");
Intent i = new Intent(Intent.ACTION_VIEW,Uri.parse("tel:12345"));
context.startActivity(i);
}
});
}
return convertView;
}
}
I am creating a android app in which i have list of channels(items) in a Custom GridView.
I have a favorite icon associated with each channel to add them in favorites list.
On click of this favorite icon the channel gets added to the Favorites List of channels.
When i use a android box remote i am not able to select the ImageView for favorite.
Instead the whole GridItem gets selected.
The single grid item is a LinearLayout which mainly has two ImageViews in it.
View code for a single grid-item of the gridview
<?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:focusable="false"
android:clickable="true"
android:orientation="vertical" >
<ImageView
android:id="#+id/channelLogo"
android:layout_width="75dip"
android:layout_height="75dip"
android:layout_gravity="center"
android:focusable="false"
android:contentDescription="#string/app_name"/>
<TextView
android:id="#+id/channelName"
android:layout_width="fill_parent"
android:focusable="false"
android:layout_height="fill_parent"
android:gravity="center"
/>
<TextView
android:id="#+id/channelStatus"
android:layout_width="fill_parent"
android:focusable="false"
android:layout_height="fill_parent"
android:gravity="center"
/>
<ImageView
android:id="#+id/addToFavourite"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:focusableInTouchMode="true"
android:clickable="true"
android:focusable="false"
android:contentDescription="Add to favourites"
android:src="#drawable/addfavorites"
/>
</LinearLayout>
Code for my grid adapter where i handle the click of the ImageView (for adding a channel to favorite).
public class GridAdapter extends BaseAdapter {
private Context mContext;
private int resourceId;
private ArrayList<Item> itemList = new ArrayList<Item>();
private ArrayList<Category> categoryList = new ArrayList<Category>();
private int size;
private Integer[] mThumbIds;
private ViewGroup gridGroup;
private static final String PREFS_FAVOURITES = "favourites";
public GridAdapter(MainActivity c, int layoutResourceId, ArrayList<Item> data, int gsize) {
mContext = c;
resourceId = layoutResourceId;
itemList = data;
size = gsize;
mThumbIds = new Integer[gsize];
for(int i=0;i<mThumbIds.length;i++) {
mThumbIds[i] = R.drawable.ic_launcher;
}
}
#Override
public int getCount() {
return size;
}
#Override
public Object getItem(int arg0) {
return mThumbIds[arg0];
}
#Override
public long getItemId(int arg0) {
return arg0;
}
class ViewHolder {
ImageView imageUrl;
TextView channelNameTxt;
TextView channelStatusTxt;
ImageView imgFavourite;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
String contextClass = mContext.getClass().toString();
ViewHolder holder;
gridGroup = parent;
View grid = null;
if(convertView==null){
grid = new View(mContext);
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
if (contextClass.contains("MainActivity") || contextClass.contains("FavoriteActivity")) {
grid = inflater.inflate(R.layout.grid_item, parent, false);
}
}else{
grid = (View)convertView;
return grid;
}
if (contextClass.contains("MainActivity")) {
if (position < itemList.size()) {
holder = new ViewHolder();
holder.channelNameTxt = (TextView) grid
.findViewById(R.id.channelName);
String channelName = itemList.get(position).getChannelName().replace("\n", "").replace("\r", "");
holder.channelNameTxt.setText(channelName);
holder.channelStatusTxt = (TextView) grid
.findViewById(R.id.channelStatus);
holder.channelStatusTxt
.setText(itemList.get(position).getStatus());
if(itemList.get(position).getStatus().equalsIgnoreCase("Online")) {
holder.channelStatusTxt.setTextColor(Color.GREEN);
} else if(itemList.get(position).getStatus().equalsIgnoreCase("Offline")) {
holder.channelStatusTxt.setTextColor(Color.RED);
}
holder.imageUrl = null;
try {
holder.imageUrl = (ImageView) grid
.findViewById(R.id.channelLogo);
holder.imageUrl.setTag(itemList.get(position).getImageUrl());
new DownloadImagesTask().execute(holder.imageUrl);
notifyDataSetChanged();
} catch (Exception ex) {
System.out.println(ex.toString());
}
final Item info = itemList.get(position);
holder.imgFavourite = (ImageView)grid.findViewById(R.id.addToFavourite);
holder.imgFavourite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//GridView gridview1;
if(mContext.getClass().toString().contains("MainActivity")) {
GridView gv = (GridView)gridGroup;
final int position = gv.getPositionForView((View) v.getParent());
Toast.makeText(mContext, "Position is :" + position, Toast.LENGTH_SHORT).show();
SharedPreferences settings = mContext.getSharedPreferences(PREFS_FAVOURITES, 0);
String favourites = settings.getString("favourites", "");
Item clicked_item = itemList.get(position);
String sep1 = "<sep1>";
String sep = "<sep>";
String favourite = clicked_item.getChannelUrl()+sep1+clicked_item.getChannelName()+sep1+clicked_item.getStatus()+sep1+"Favorite"+sep1+clicked_item.getImageUrl()+sep;
favourite = favourite.replace("\n", "").replace("\r", "");
if(!favourites.contains(favourite))
favourites = favourites+favourite;
SharedPreferences.Editor editor = settings.edit();
editor.putString("favourites", favourites);
editor.commit();
}
}
});
grid.setTag(holder);
}
}
return grid;
}
This works fine on a android phone.
below is my code which works fine for showing listview horizontally. how can I change it to gridvew. What changes should I make to change it to gridview? help me please
public class fifthscreen extends Activity {
int IOConnect = 0;
String _response;
String status;
HorizontalListView listview;
CategoryListAdapter3 cla;
String URL, URL2;
String SelectMenuAPI;
static ArrayList<Long> Category_ID = new ArrayList<Long>();
static ArrayList<String> Category_name = new ArrayList<String>();
static ArrayList<String> Category_image = new ArrayList<String>();
public static String allergen2;
String name;
String url1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fifthscreen);
listview = (HorizontalListView) this.findViewById(R.id.listview2);
cla = new CategoryListAdapter3(fifthscreen.this);
new TheTask().execute();
}
public class TheTask extends AsyncTask<Void, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(Void... arg0) {
try {
HttpGet request = new HttpGet(url);
HttpResponse response = client.execute(request);
HttpEntity resEntity = response.getEntity();
_response = EntityUtils.toString(resEntity);
} catch (Exception e) {
e.printStackTrace();
}
return _response;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
JSONObject json2 = new JSONObject(result);
status = json2.getString("status");
if (status.equals("1")) {
JSONArray school4 = json2.getJSONArray("dish_allergen");
//
for (int i = 0; i < school4.length(); i++) {
JSONObject object = school4.getJSONObject(i);
Category_ID.add((long) i);
Category_name.add(object.getString("name"));
Category_image.add(object.getString("image"));
}
}
else {
JSONArray school2 = json2.getJSONArray("data");
for (int i = 0; i < school2.length(); i++) {
JSONObject object = school2.getJSONObject(i);
Category_ID.add((long) i);
Category_name.add(object.getString("name"));
}
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
listview.setAdapter(cla);
}
}
}
public class CategoryListAdapter3 extends BaseAdapter {
private Activity activity;
private AQuery androidAQuery;
public CategoryListAdapter3(Activity act) {
this.activity = act;
// imageLoader = new ImageLoader(act);
}
public int getCount() {
// TODO Auto-generated method stub
return fifthscreen.Category_ID.size();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder holder;
androidAQuery = new AQuery(getcontext());
if(convertView == null){
LayoutInflater inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.viewitem2, null);
holder = new ViewHolder();
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
holder.txtText = (TextView) convertView.findViewById(R.id.title2);
holder.imgThumb = (ImageView) convertView.findViewById(R.id.image2);
holder.txtText.setText(fifthscreen.Category_name.get(position));
// imageLoader.DisplayImage(fifthscreen.Category_image.get(position),
activity, holder.imgThumb);
androidAQuery.id(holder.imgThumb).image(fifthscreen.Category_image.get(position), false,
false);
return convertView;
}
private Activity getcontext() {
// TODO Auto-generated method stub
return null;
}
static class ViewHolder {
TextView txtText;
ImageView imgThumb;
}
}
<!--- fifithscreen.xml--->
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_below="#+id/test_button_text5"
android:orientation="vertical" >
<com.example.examplecode.HorizontalListView
android:id="#+id/listview2"
android:layout_width="wrap_content"
android:layout_height="120dp"
android:layout_below="#+id/test_button_text5"
android:background="#ffffff"/>
</LinearLayout>
<!--viewitem2.xml--->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<ImageView
android:id="#+id/image2"
android:layout_width="90dp"
android:layout_height="70dp"
android:scaleType="fitXY"
android:padding="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:src="#drawable/ic_launcher"
/>
<TextView
android:id="#+id/title2"
android:layout_width="90dp"
android:layout_height="wrap_content"
android:textColor="#000"
android:paddingTop="10dp"
android:gravity="center_horizontal"
/>
</LinearLayout>
No change at all. Just set adapter of GridView as your are setting for ListView.
I'd suggest that you use RecyclerView intead.
You might want to refer to the documentation and learn more about it.
I'm sharing my piece of code in which I'm changing my gridview to listview using RecyclerView
If you're using Android Studio then you might need to add dependencies in gradle build. In my case I added as follows:
dependencies {
.
.
.
compile 'com.android.support:recyclerview-v7:24.0.0'
}
First I'm defining a grid cell which is to be used in grid layout
recycler_cell.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="#+id/imageView2"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:background="#FF000000"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="Small Text"
android:id="#+id/textView2"
android:layout_below="#+id/imageView2"
android:layout_alig=nParentStart="true"
android:layout_alignEnd="#+id/imageView2"
android:gravity="center"/>
</RelativeLayout>
Now I'm defining a list row which is to be used in list layout
recycler_row.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="#+id/imageView"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:background="#FF000000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:id="#+id/textView"
android:layout_alignParentTop="true"
android:layout_alignBottom="#+id/imageView"
android:layout_alignParentEnd="true"
android:layout_toEndOf="#+id/imageView"
android:gravity="center_vertical"
android:background="#FF333333"
android:textColor="#FFF"
android:padding="10dp"/>
</RelativeLayout>
recycler_view_test.xml
And of course define a layout which would contain RecyclerView
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/recyclerView"
android:layout_alignParentLeft="true"
android:layout_marginLeft="0dp"
android:layout_alignParentTop="true"
android:layout_marginTop="0dp"
android:layout_centerHorizontal="true"
>
</android.support.v7.widget.RecyclerView>
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Change Layout"
android:id="#+id/btnChange"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="62dp"/>
</RelativeLayout>
I'm sharing my piece of code but I'd strongly recommend that you go through the documentation and tutorials to understand RecyclerView to its full extent.
public class RecyclerViewTest extends AppCompatActivity
{
final int GRID = 0;
final int LIST = 1;
int type;
RecyclerView recyclerView;
RecyclerView.LayoutManager gridLayoutManager, linearLayoutManager;
MyAdapter adapter;
Button btnChange;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.recycler_view_test);
// Display contents in views
final List<Person> list = new ArrayList<>();
list.add(new Person("Ariq Row 1"));
list.add(new Person("Ariq Row 2"));
list.add(new Person("Ariq Row 3"));
// Finding views by id
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
btnChange = (Button) findViewById(R.id.btnChange);
// Defining Linear Layout Manager
linearLayoutManager = new LinearLayoutManager(getApplicationContext());
// Defining Linear Layout Manager (here, 3 column span count)
gridLayoutManager = new GridLayoutManager(getApplicationContext(), 3);
//Setting gird view as default view
type = GRID;
adapter = new MyAdapter(list, GRID);
recyclerView.setLayoutManager(gridLayoutManager);
recyclerView.setAdapter(adapter);
//Setting click listener
btnChange.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
if (type == LIST)
{
// Change to grid view
adapter = new MyAdapter(list, GRID);
recyclerView.setLayoutManager(gridLayoutManager);
recyclerView.setAdapter(adapter);
type = GRID;
}
else
{
// Change to list view
adapter = new MyAdapter(list, LIST);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(adapter);
type = LIST;
}
}
});
}
}
//Defining Adapter
class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>
{
List<Person> list;
int type;
final int GRID = 0;
final int LIST = 1;
MyAdapter(List<Person> list, int type)
{
this.list = list;
this.type = type;
}
// Inflating views if the existing layout items are not being recycled
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View itemView;
if (viewType == GRID)
{
// Inflate the grid cell as a view item
itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_cell, parent, false);
}
else
{
// Inflate the list row as a view item
itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_row, parent, false);
}
return new ViewHolder(itemView, viewType);
}
// Add data to your layout items
#Override
public void onBindViewHolder(ViewHolder holder, int position)
{
Person person = list.get(position);
holder.textView.setText(person.name);
}
// Number of items
#Override
public int getItemCount()
{
return list.size();
}
// Using the variable "type" to check which layout is to be displayed
#Override
public int getItemViewType(int position)
{
if (type == GRID)
{
return GRID;
}
else
{
return LIST;
}
}
// Defining ViewHolder inner class
public class ViewHolder extends RecyclerView.ViewHolder
{
TextView textView;
final int GRID = 0;
final int LIST = 1;
public ViewHolder(View itemView, int type)
{
super(itemView);
if (type == GRID)
{
textView = (TextView) itemView.findViewById(R.id.textView2);
}
else
{
textView = (TextView) itemView.findViewById(R.id.textView);
}
}
}
}
// Data Source Class
class Person
{
String name;
Person(String name)
{
this.name = name;
}
}
If you end up with the issue to auto fit the number of columns in case of grid layout then you might want to check #s-marks's answer in which he extended the GridLayoutManager class and added his own patch of code, and also my fix if you start having weird column width.
In my case, using his solution I made a class as follows:
class GridAutofitLayoutManager extends GridLayoutManager
{
private int mColumnWidth;
private boolean mColumnWidthChanged = true;
public GridAutofitLayoutManager(Context context, int columnWidth)
{
/* Initially set spanCount to 1, will be changed automatically later. */
super(context, 1);
setColumnWidth(checkedColumnWidth(context, columnWidth));
}
public GridAutofitLayoutManager(Context context, int columnWidth, int orientation, boolean reverseLayout)
{
/* Initially set spanCount to 1, will be changed automatically later. */
super(context, 1, orientation, reverseLayout);
setColumnWidth(checkedColumnWidth(context, columnWidth));
}
private int checkedColumnWidth(Context context, int columnWidth)
{
if (columnWidth <= 0)
{
/* Set default columnWidth value (48dp here). It is better to move this constant
to static constant on top, but we need context to convert it to dp, so can't really
do so. */
columnWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 48,
context.getResources().getDisplayMetrics());
}
else
{
columnWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, columnWidth,
context.getResources().getDisplayMetrics());
}
return columnWidth;
}
public void setColumnWidth(int newColumnWidth)
{
if (newColumnWidth > 0 && newColumnWidth != mColumnWidth)
{
mColumnWidth = newColumnWidth;
mColumnWidthChanged = true;
}
}
#Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state)
{
int width = getWidth();
int height = getHeight();
if (mColumnWidthChanged && mColumnWidth > 0 && width > 0 && height > 0)
{
int totalSpace;
if (getOrientation() == VERTICAL)
{
totalSpace = width - getPaddingRight() - getPaddingLeft();
}
else
{
totalSpace = height - getPaddingTop() - getPaddingBottom();
}
int spanCount = Math.max(1, totalSpace / mColumnWidth);
setSpanCount(spanCount);
mColumnWidthChanged = false;
}
super.onLayoutChildren(recycler, state);
}
}
Then you simply have to change:
gridLayoutManager = new GridLayoutManager(getApplicationContext(), 3);
and use your custom grid layout object, here 100 is the width of columns in dp
gridLayoutManager = new GridAutofitLayoutManager(getApplicationContext(), 100);
You can do something like this:
For the layout of the grid/list use a merge:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ViewStub android:id="#+id/list"
android:inflatedId="#+id/showlayout"
android:layout="#layout/list_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"/>
<ViewStub android:id="#+id/grid"
android:inflatedId="#+id/showlayout"
android:layout="#layout/grid_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"/>
</merge>
then define the layout for the list and the grid (and also for their items), and manage the passage between them inflating the layouts, and then use a method like this to change the current view:
private void changeView() {
//if the current view is the listview, passes to gridview
if(list_visibile) {
listview.setVisibility(View.GONE);
gridview.setVisibility(View.VISIBLE);
list_visibile = false;
setAdapters();
}
else {
gridview.setVisibility(View.GONE);
listview.setVisibility(View.VISIBLE);
list_visibile = true;
setAdapters();
}
}
If you need the complete code, it is available in this article:
http://pillsfromtheweb.blogspot.it/2014/12/android-passare-da-listview-gridview.html
Just take a GridView object instead of Listview like :
GridView gridView;
gridView= (GridView) this.findViewById(R.id.gridView1);
And in you getView method of CategoryListAdapter3 do like :
convertView = inflater.inflate(R.layout.your_grid_item_leyout, null);
And at last in onPostExecute of TheTask do like :
gridView.setAdapter(cla);
That's It.
Use GridView instead of below:
Then replace
listview = (HorizontalListView) this.findViewById(R.id.listview2);
to
GridView gridview;
gridview=(GridView) findViewById(R.id.gridview);
Everything else are fine, just set Adapter using GridView object. And you are done.
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
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.