spinner initialization in a custom view - android

I try to make a custom view but I've got a problem with the spinner.
When I launch the application everything is ok. Preferences are read and the spinner setSelection method work great (display picture is ok).
When I change the spinner value, there is no problem too : Preferences are saved and when I start the application the new choice is display.
My problem comes when rotating the device, all my spinner value are reset to the last spinner value (vv2 in my code). I really don't understand...
Here is my code :
The widget_value_view.xml
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
<Spinner
android:id="#+id/my_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:background="#android:color/transparent" />
<TextView
android:id="#+id/my_value_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_centerVertical="true"
android:background="#android:color/transparent" />
</merge>
The ValueView.java class :
package com.example.spinnertest;
import java.util.Arrays;
import java.util.List;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
public class ValueView extends LinearLayout {
protected TextView mValueTv = null;
protected Spinner mSpinner = null;
protected List<String> mChoiceList;
private MySpinnerAdapter mSpinnerAdapter;
public ValueView(Context context) {
super(context);
}
public ValueView(Context context, AttributeSet attributes){
super(context,attributes);
TypedArray a = context.getTheme().obtainStyledAttributes(attributes,R.styleable.ValueView,0, 0);
try {
String valueList = a.getString(R.styleable.ValueView_valueList);
mChoiceList = Arrays.asList(valueList.split("\\|"));
} finally {
a.recycle();
}
setOrientation(LinearLayout.HORIZONTAL);
setGravity(Gravity.CENTER_VERTICAL);
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.widget_value_view, this, true);
mSpinner = (Spinner) getChildAt(0);
mValueTv = (TextView) getChildAt(1);
mSpinnerAdapter = new MySpinnerAdapter(context, mChoiceList);
mSpinner.setAdapter(mSpinnerAdapter);
}
/**
* Change textview value
*/
public void setValue(double value,String format){
mValueTv.setText("todo");
invalidate();
requestLayout();
}
/**
* Set the current item of the spinner
* #param position of the item
*/
public void setSelection(int position, boolean animate) {
// mSpinnerAdapter.notifyDataSetChanged();
mSpinner.setSelection(position,animate);
// invalidate();
// requestLayout();
}
public int getSelectedItemPosition() {
return mSpinner.getSelectedItemPosition();
}
}
In this class I use a adapter define with 2 layout and one class :
MySpinnerAdapter.java
package com.example.spinnertest;
import java.util.List;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class MySpinnerAdapter extends BaseAdapter {
public static final String ITEM_ALTITUDE = "altitude";
public static final String ITEM_SPEED = "speed";
public static final String ITEM_DISTANCE = "distance";
private static final String LOG_TAG = "SPINNER_TEST";
private Context mContext;
private List<String> mChoiceList;
public MySpinnerAdapter(Context context, List<String> values) {
this.mContext = context;
this.mChoiceList = values;
}
#Override
public int getCount() {
return mChoiceList.size();
}
#Override
public Object getItem(int position) {
return mChoiceList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater layout = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layout.inflate(R.layout.item_spinner_value, null);
}
ImageView imView = (ImageView) convertView.findViewById(R.id.item_spinner_value_iv);
Log.d(LOG_TAG,"Spinner Adapter position = " + String.valueOf(position));
imView.setImageResource(getSpinnerItemImage(position));
return convertView;
}
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater layout = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layout.inflate(R.layout.item_spinner_list, null);
}
ImageView imView = (ImageView) convertView.findViewById(R.id.item_spinner_list_iv);
TextView textView = (TextView) convertView.findViewById(R.id.item_spinner_list_tv);
textView.setText(mChoiceList.get(position));
imView.setImageResource(getSpinnerItemImageSmall(position));
return convertView;
}
private int getSpinnerItemImageSmall(int position) {
String item = mChoiceList.get(position);
if (item.equals(ITEM_ALTITUDE)) {
return R.drawable.altitude_small;
} else if (item.equals(ITEM_DISTANCE)) {
return R.drawable.distance_small;
} else if (item.equals(ITEM_SPEED)) {
return R.drawable.vitesse_small;
} else {
return R.drawable.date_small;
}
}
private int getSpinnerItemImage(int position) {
String item = mChoiceList.get(position);
if (item.equals(ITEM_ALTITUDE)) {
return R.drawable.altitude;
} else if (item.equals(ITEM_DISTANCE)) {
return R.drawable.distance;
} else if (item.equals(ITEM_SPEED)) {
return R.drawable.vitesse;
} else {
return R.drawable.date;
}
}
}
and the 2 layout item_spinner_list.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" >
<ImageView
android:id="#+id/item_spinner_list_iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:padding="5dp"
android:src="#android:drawable/ic_menu_gallery" />
<TextView
android:id="#+id/item_spinner_list_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:padding="5dp"
android:layout_toRightOf="#+id/item_spinner_list_iv"
android:text="Durée" />
</RelativeLayout>
and item_spinner_value.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"
android:background="#android:color/transparent" >
<ImageView
android:id="#+id/item_spinner_value_iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:padding="5dp"
android:src="#android:drawable/ic_menu_gallery" />
</RelativeLayout>
and finally my MainActivity.java
package com.example.spinnertest;
import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
public class MainActivity extends Activity {
private SharedPreferences mPref;
private ValueView mVv1;
private ValueView mVv2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
mVv1 = (ValueView)findViewById(R.id.value1);
mVv2 = (ValueView)findViewById(R.id.value2);
mVv1.setSelection(mPref.getInt("pref_val1", 0),false);
mVv2.setSelection(mPref.getInt("pref_val2", 1),false);
}
#Override
public void onPause() {
SharedPreferences.Editor editor = mPref.edit();
editor.putInt("pref_val1", mVv1.getSelectedItemPosition());
editor.putInt("pref_val2", mVv2.getSelectedItemPosition());
editor.commit();
super.onPause();
}
}
and the layout :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res/com.example.spinnertest"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.spinnertest.ValueView
android:id="#+id/value1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_margin="10dp"
android:background="#android:color/transparent"
custom:valueList="speed|altitude|distance" />
<com.example.spinnertest.ValueView
android:id="#+id/value2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/value1"
android:layout_margin="10dp"
custom:valueList="speed|altitude|distance" />
</RelativeLayout>

I cannot really explain why your code is not working, but I would prefer to save the state of the spinner locally (I mean in the activity); it's the normal Android workflow for screen rotation.
Something like this:
String MVV1="1";
String MVV2="2";
#Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
mPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
mVv1 = (ValueView)findViewById(R.id.value1);
mVv2 = (ValueView)findViewById(R.id.value2);
if (savedInstanceState != null) {
mVv1.setSelection(savedInstanceState.getInt(MVV1),false);
mVv2.setSelection(savedInstanceState.getInt(MVV2),false);
}
else{
mVv1.setSelection(mPref.getInt("pref_val1", 0),false);
mVv2.setSelection(mPref.getInt("pref_val2", 1),false);
}
}
#Override
public void onPause() {
SharedPreferences.Editor editor = mPref.edit();
editor.putInt("pref_val1", mVv1.getSelectedItemPosition());
editor.putInt("pref_val2", mVv2.getSelectedItemPosition());
editor.commit();
super.onPause();
}
#Override
protected void onSaveInstanceState (Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(MVV1, mVv1.getSelectedItemPosition());
outState.putInt(MVV2, mVv2.getSelectedItemPosition());
}
My syntax is maybe not perfect because I wrote it in the SO editor but hope you got the idea: the status is written in the Preferences as soon as the Activity is paused but if the activity rotates (your method should work but maybe is there a cache to access to the preferences or something...) then, it'll use the specific bundle for it: the one which is filled just when the screen rotates and used when the screen is recreated.
Test it and say if it's working ;)

Related

Not being able to place an onClickListener on the Grid Items provided by a custom BaseAdapter

I currently have a grid view using a base adapter inside a fragment and I am trying to transfer to a different fragment when one of the items is clicked but none of the solutions I found on stack overflow has worked. I might miss something.
Adapter
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.licenta.joberfrontend.R;
import com.licenta.joberfrontend.rest.backend_entieties.Category;
import java.util.ArrayList;
import java.util.List;
public class CategoriesAdapter extends BaseAdapter {
public class ViewHolder {
TextView textName;
ImageView imageView;
}
private ArrayList<Category> categoryList;
public Context context;
public CategoriesAdapter(List<Category> apps, Context context) {
this.context = context;
this.categoryList = (ArrayList<Category>) apps;
}
#Override
public int getCount() {
return categoryList.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View view, ViewGroup parent) // inflating the layout and initializing widgets
{
ViewHolder viewHolder;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.category_list_content, parent, false);
viewHolder = new ViewHolder();
viewHolder.textName = view.findViewById(R.id.textName);
viewHolder.imageView = view.findViewById(R.id.iconView);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
// here we are setting up the names and images
viewHolder.textName.setText(categoryList.get(position).getName());
viewHolder.imageView.setImageResource(this.context.getResources().getIdentifier(categoryList.get(position).getCategoryIconId(), "mipmap", this.context.getPackageName()));
return view;
}
}
Fragment's OnCreate
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final LocalStorageSaver localStorageSaver = new LocalStorageSaver(Objects.requireNonNull(getContext()));
final ToastShower toastShower = new ToastShower();
//REST services creation
final RetrofitCreator retrofitCreator = new RetrofitCreator();
final Retrofit retrofit = retrofitCreator.getRetrofit();
final CategoryService categoryService = retrofit.create(CategoryService.class);
final Call<List<Category>> getCategoriesRequest = categoryService.getAllCategoriesAndTheirJobs(localStorageSaver.getValueFromStorage(Constants.TOKEN));
getCategoriesRequest.enqueue(
new Callback<List<Category>>() {
#Override
public void onResponse(Call<List<Category>> call, Response<List<Category>> response) {
toastShower.showToast("Categories succesfully retrieved from backend.", getContext());
final GridView gridView = Objects.requireNonNull(getView()).findViewById(R.id.gridViewNewContract);
gridView.setAdapter(new CategoriesAdapter(response.body(), getActivity()));
}
#Override
public void onFailure(Call<List<Category>> call, Throwable t) {
toastShower.showToast("There has been a problem with retrieving the categories data!", getContext());
}
}
);
}
Items inside the grid view
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.cardview.widget.CardView
android:layout_width="100dp"
android:layout_height="100dp"
app:cardCornerRadius="15dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal|center_vertical"
android:layout_marginLeft="10dp"
android:layout_marginTop="15dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="15dp"
android:orientation="vertical">
<ImageView
android:id="#+id/iconView"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center_horizontal"
android:src="#mipmap/ic_list"
android:tint="#color/colorAccent" />
<TextView
android:id="#+id/textName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:fontFamily="sans-serif"
android:maxLength="12"
android:text="#string/appName"
android:textColor="#color/colorAccent"
android:textSize="13sp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</RelativeLayout>
If you need any more information I will gladly provided.
I can mention that I've tried placing listeners both in the adapter and in the fragment directly on the grid.
please try this
viewHolder.imageView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//do stuff
}
});

I am new in android,i want to delete a row on clicking delete button that are shown in front of each row in list view

This is may XML class random values in which we make a row that I want to delete
randomvalues.xml
<LinearLayout
android:id="#+id/linear"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_below="#+id/addbtn">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/img"
android:layout_width="30dp"
android:layout_height="40dp"
android:src="#drawable/img1"
/>
<LinearLayout
android:layout_width="255dp"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#339966"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/adress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Address"
android:textColor="#606060" />
</LinearLayout>
</LinearLayout>
<ImageButton
android:id="#+id/removebtn"
android:layout_width="30dp"
android:layout_height="40dp"
android:src="#drawable/remove"/>
</LinearLayout>
</LinearLayout>
this is my activity_main XML in which i used a list view to show a row that I make in random values XML file
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.chaqeel.taskviews.MainActivity">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/linear">
<ImageButton
android:id="#+id/addbtn"
android:layout_width="30dp"
android:layout_height="40dp"
android:src="#drawable/add"
android:layout_marginLeft="280dp"/>
</LinearLayout>
<ListView
android:id="#+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/linear"
>
</ListView>
</RelativeLayout>
This is MainActivity.java in which we used a array to show the values
MainActivity.java
package com.example.chaqeel.taskviews;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Collections;
public class MainActivity extends Activity {
ListView lv;
String[] Names = {"Aqeel", "Ali", "Ansar", "Usama", "Farhad"};
String[] Address = {"Chakwal", "Rawalpindi", "Islamabad", "Lahore",
"Multan"};
int[] Images = {R.drawable.img1, R.drawable.img2, R.drawable.img3,
R.drawable.img4, R.drawable.img5};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.listview);
lv.setAdapter(new dataListAdapter(Names, Address, Images));
}
class dataListAdapter extends BaseAdapter {
String[] Name, Addres;
int[] imge;
/*dataListAdapter() {
Name = null;
Addres = null;
imge=null;
}*/
public dataListAdapter(String[] text, String[] text1, int[] text3) {
Name = text;
Addres = text1;
imge = text3;
}
public int getCount() {
return Name.length;
}
public Object getItem(int arg0) {
return null;
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup
parent) {
LayoutInflater inflater = getLayoutInflater();
final View row;
row = inflater.inflate(R.layout.randomvalues, parent, false);
final TextView Name, Addres;
ImageView imge;
Name = (TextView) row.findViewById(R.id.name);
Addres = (TextView) row.findViewById(R.id.adress);
imge = (ImageView) row.findViewById(R.id.img);
Name.setText(Names[position]);
Addres.setText(Address[position]);
imge.setImageResource(Images[position]);
final ArrayList<String> lvv= new ArrayList<>();
Collections.addAll(lvv,Names);
// Collection.addAll(lvv,Address);
ImageButton dltbutton = (ImageButton) findViewById(R.id.removebtn);
dltbutton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
lvv.remove(Names);
lvv.remove(Address);
notifyDataSetChanged();
}
});
return (row);
}
}
}
In the onClickListener try the following code
youradapter.notifyDataSetChanged();
In the deletebutton onClickListener try this
Names = ArrayUtils.removeElement(Names,Names[position]);
Address = ArrayUtils.removeElement(Address,Address[position]);
notifyDataSetChanged();
Though it is advised to use OOP concept like a class to hold the Arrays of Names,Address and Images.
Try below code:
dltbutton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Name = ArrayUtils.removeElement(Names, Names[position]);
Address = ArrayUtils.removeElement(Address, Address[position]);
imge = ArrayUtils.removeElement(imge, imge[position]);
notifyDataSetChanged();
}
});
change this:
ImageButton dltbutton = (ImageButton) findViewById(R.id.removebtn);
dltbutton.setTag(position);
dltbutton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Integer index = (Integer) view.getTag();
lvv.remove(index.intValue());
notifyDataSetChanged();
}
});
Are you from Chakwal? I am Chakwalian. Again StackOverflow is telling me that my answer does not meet thier quality requirements.
You need to better idea to use Model class as below:-
create a model class MyModel.class
import java.util.ArrayList;
import java.util.List;
public class MyModel {
String Name, Address;
int image;
public MyModel(String name, String address, int image) {
Name = name;
Address = address;
this.image = image;
}
public String getName() {
return Name;
}
public String getAddress() {
return Address;
}
public int getImage() {
return image;
}
}
and then add with adapter class see below:
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends Activity {
ListView lv;
String[] Names = {"Aqeel", "Ali", "Ansar", "Usama", "Farhad"};
String[] Address = {"Chakwal", "Rawalpindi", "Islamabad", "Lahore",
"Multan"};
int[] Images = {R.drawable.ic_menu_camera, R.drawable.ic_menu_gallery, R.drawable.ic_menu_manage,
R.drawable.ic_menu_send, R.drawable.ic_menu_share};
private List<MyModel> myModel=new ArrayList<>();
private DataListAdapter dataListAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_main);
lv = (ListView) findViewById(R.id.listview);
for(int i=0;i<Names.length;i++){
myModel.add( new MyModel(Names[i],Address[i],Images[i]));
}
dataListAdapter=new DataListAdapter(myModel);
lv.setAdapter(dataListAdapter);
}
class DataListAdapter extends BaseAdapter {
private List<MyModel> myModel=new ArrayList<>();
public DataListAdapter(List<MyModel> myModel) {
this.myModel=myModel;
}
public int getCount() {
return myModel.size();
}
public Object getItem(int arg0) {
return null;
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, final ViewGroup
parent) {
LayoutInflater inflater = getLayoutInflater();
final View row;
row = inflater.inflate(R.layout.randomevalue, parent, false);
final TextView Name, Addres;
ImageView imge;
Name = (TextView) row.findViewById(R.id.name);
Addres = (TextView) row.findViewById(R.id.adress);
imge = (ImageView) row.findViewById(R.id.img);
Name.setText(myModel.get(position).getName());
Addres.setText(myModel.get(position).getAddress());
imge.setImageResource(myModel.get(position).getImage());
ImageButton dltbutton = (ImageButton) row.findViewById(R.id.removebtn);
dltbutton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
myModel.remove(position);
notifyDataSetChanged();
}
});
return (row);
}
}
public void addMore(View v)
{
myModel.add( new MyModel("Mahesh","India",R.drawable.ic_menu_share));
dataListAdapter.notifyDataSetChanged();
}
}
public void addMore(View v)
{
myModel.add( new MyModel("Mahesh","India",R.drawable.ic_menu_share));
dataListAdapter.notifyDataSetChanged();
}
add android:onClick="addMore" to your add button
it will fine Happy Coding :)
#Override
public boolean onContextItemSelected(MenuItem item) {
// TODO Auto-generated method stub
AdapterContextMenuInfo info =(AdapterContextMenuInfo) item.getMenuInfo();
pos=info.position;
deleteditem=myList.get(pos);
if(item.getTitle()=="Delete")
{
String delete = myList.get(pos);
File f = new File(path + "/"+ delete);
if (f != null && f.exists())
{
f.delete();
}
myList.remove(pos);
adapter. notifyDataSetChanged();
Toast.makeText(getApplicationContext(), "item has deleted",Toast.LENGTH_LONG).show();
}

ListFragment and Custom Adapter Issue

Two issue with List Fragment: 1. I have a class that extends ListFragments.In the onCreated, I am setting my custom Adapter. The issue is that when the user logs in, the adadpter is null and would not have a value until the user searches for an owner. As a result, it throws an exception when it tries to set up the listadapter and it finds the ArrayAdapter object to be null. I have a custome layout that has a listview and a textview, but I still gets the error. See sample code below. I bold the line of code where the issue happens. Also, I bold few other section where I think it may be important to notice.
I implemented Parcelable in the class "Owner" so that I can pass the object as a ParcelableArray. Even though the object is not null, retrieving it in the OwnerDetail class shows null as if I did not pass it it. I've seen several example, but I am not able to get it right. What am I doing wrong here?
Note: If I were to call the AsyncTask in the OwnerDetail class and set the ListAdapter, it will work fine. The issue with that is that it will display a list of owners as soon as the user is logged in which is not the expected behavior. The behavior that I want is to login first, search for an owner, display the owner, double click on an owner, and finally display a list of cars that the owner owns. I am doing this project, so I can learn how to use ListFraments.
// Here is the entire code
package com.mb.carlovers;
import android.os.Parcel;
import android.os.Parcelable;
public class Car implements Parcelable {
private String _make;
private String _model;
private String _year;
public Car()
{
this._make = "";
this._model = "";
this._year = "";
}
public Car(String make)
{
this._make = make;
}
public Car(String make, String year)
{
this._make = make;
this._year = year;
}
public Car(String make, String model, String year)
{
this._make = make;
this._model = model;
this._year = year;
}
//Getters
public String getMake()
{
return _make;
}
public String getModel()
{
return _model;
}
public String getYear()
{
return _year;
}
//Setters
public void setMake(String make)
{
_make = make;
}
public void setModel(String model)
{
_model = model;
}
public void setYear(String year)
{
_year = year;
}
#Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
// TODO Auto-generated method stub
}
}
package com.mb.carlovers;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
public class CarDetail extends ListFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.customize_layout,container,false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
String[] myCars = {};
super.onActivityCreated(savedInstanceState);
ArrayAdapter<String> carAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_activated_1, myCars);
setListAdapter(carAdapter);
}
}
package com.mb.carlovers;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class Login extends Activity implements OnClickListener{
private Button btnLogin;
private EditText etUsername, etPassword;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
initializeVariables();
}
public void initializeVariables()
{
btnLogin = (Button) this.findViewById(R.id.bLogin);
etUsername = (EditText)this.findViewById(R.id.etUserName);
etPassword = (EditText)this.findViewById(R.id.etPassword);
btnLogin.setOnClickListener(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.login, menu);
return true;
}
#Override
public void onClick(View v) {
Log.i("Tag", "In Onclick Litener");
String uName = etUsername.getText().toString();
String pWord = etPassword.getText().toString();
if(uName.equals("owner") && pWord.equals("1234"))
{
Log.i("Tag", "username =" + uName + "Password =" + pWord);
Intent intent = new Intent(this, People.class);
startActivity(intent);
}
}
}
package com.mb.carlovers;
import android.os.Parcel;
import android.os.Parcelable;
public class Owner implements Parcelable {
private String _firstName;
private String _lastName;
private String _carId;
private Car _car;
public Owner()
{
this._firstName = "";
this._lastName = "";
this._carId = "";
}
public Owner(String lName)
{
this._lastName = lName;
}
public Owner(String lName, String cId)
{
this._lastName = lName;
this._carId = cId;
}
public Owner(String lName, String fName, String cId)
{
this._lastName = lName;
this._firstName = fName;
this._carId = cId;
}
public Owner(String lName, String fName, String cId, Car car)
{
this._lastName = lName;
this._firstName = fName;
this._carId = cId;
this._car = car;
}
//Getters
public String getFirstName()
{
return _firstName;
}
public String getLastName()
{
return _lastName;
}
public String getCarId()
{
return _carId;
}
public Car getCar()
{
return _car;
}
//Setters
public void setFirstName(String fName)
{
_firstName = fName;
}
public void setLastName(String lName)
{
_lastName = lName;
}
public void setCarId(String cId)
{
_carId = cId;
}
public void setCar(Car car)
{
_car = car;
}
#Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(_firstName);
dest.writeString(_lastName);
dest.writeString(_carId);
dest.writeParcelable(_car, flags);
}
public Owner(Parcel source){
_firstName = source.readString();
_lastName = source.readString();
_carId = source.readString();
_car = source.readParcelable(Car.class.getClassLoader());
}
public class MyCreator implements Parcelable.Creator<Owner> {
public Owner createFromParcel(Parcel source) {
return new Owner(source);
}
public Owner[] newArray(int size) {
return new Owner[size];
}
}
}
package com.mb.carlovers;
import com.mb.carlovers.adapter.OwnerAdapter;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class OwnerDetail extends ListFragment {
OwnerAdapter ownerAdapter = null;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.customize_layout,container, false);
}
#Override
public void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
}
#Override
public void onCreate(Bundle savedInstanceState) {
Owner[] myOwners = null;
super.onCreate(savedInstanceState);
Bundle values = getActivity().getIntent().getExtras();
if(values != null)
{
myOwners = (Owner[]) values.getParcelableArray("test");
}
super.onActivityCreated(savedInstanceState);
ownerAdapter = new OwnerAdapter(getActivity(), R.layout.owner_detail , myOwners);
ownerAdapter.notifyDataSetChanged();
}
package com.mb.carlovers;
import java.util.List;
import com.mb.carlovers.asynctask.OnwerAsyncTask;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
public class People extends FragmentActivity implements OnClickListener, OnItemSelectedListener {
private Button search;
private EditText etSearchBy, etSearchByID;
private Spinner spOption;
private String selectedOption = null;
private TextView tvErrorMessage;
#Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
setContentView(R.layout.people);
InitializeVariables();
}
private void InitializeVariables()
{
etSearchBy = (EditText) this.findViewById(R.id.etByLastName);
etSearchByID = (EditText) this.findViewById(R.id.etCarID);
spOption = (Spinner) this.findViewById(R.id.spOption);
search = (Button) this.findViewById(R.id.bSearch);
search.setOnClickListener(this);
tvErrorMessage = (TextView) this.findViewById(R.id.tvErrorMessage);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,R.array.spOptions, android.R.layout.simple_spinner_dropdown_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spOption.setAdapter(adapter);
spOption.setOnItemSelectedListener(this);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
#Override
protected void onPause() {
super.onPause();
}
#Override
public void onClick(View v) {
String searchByName = etSearchBy.getText().toString();
String searchById = etSearchByID.getText().toString();
if(selectedOption == null || selectedOption == "All")
{
if(searchByName.matches("") || searchById.matches(""))
{
tvErrorMessage.setText("You must select a last name and car id");
} else
{
}
} else if(selectedOption == "Name")
{
if(!searchByName.matches(""))
{
OnwerAsyncTask asynTask = new OnwerAsyncTask();
List<Owner> lt = null;
try {
lt = asynTask.execute("").get();
} catch (Exception e) {
e.printStackTrace();
}
Owner myOwners[] = lt.toArray(new Owner[lt.size()]);
Bundle data = new Bundle();
data.putParcelableArray("test", myOwners);
} else
{
tvErrorMessage.setText("You must enter the last name of the owner.");
}
} else if (selectedOption == "ID")
{
if(!searchById.matches(""))
{
String st = null;
String d = st;
} else
{
tvErrorMessage.setText("You must enter the car id that you'd like to search.");
}
}
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int pos,long id) {
switch(pos)
{
case 0:
selectedOption = "All";
break;
case 1:
selectedOption ="Name";
break;
case 2:
selectedOption ="ID";
break;
default:
selectedOption = null;
break;
}
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
selectedOption ="ALL";
}
}
package com.mb.carlovers.adapter;
import com.mb.carlovers.Car;
import com.mb.carlovers.R;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class CarAdapter extends ArrayAdapter<Car> {
private Context context;
private int layoutResourceId;
private Car data[] = null;
public CarAdapter(Context context, int resource, Car[] data) {
super(context, resource, data);
this.context = context;
this.layoutResourceId = resource;
this.data = data;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
CarHolder holder = null;
if(row == null)
{
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new CarHolder();
holder.tvMake = (TextView) row.findViewById(R.id.tvMake);
holder.tvModel = (TextView) row.findViewById(R.id.tvModel);
holder.tvYear = (TextView) row.findViewById(R.id.tvYear);
row.setTag(holder);
} else
{
holder = (CarHolder) row.getTag();
}
Car item = data[position];
holder.tvMake.setText(item.getMake().toString());
holder.tvModel.setText(item.getModel().toString());
holder.tvYear.setText(item.getYear().toString());
return row;
}
public static class CarHolder
{
TextView tvMake;
TextView tvModel;
TextView tvYear;
}
}
package com.mb.carlovers.adapter;
import com.mb.carlovers.Owner;
import com.mb.carlovers.R;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class OwnerAdapter extends ArrayAdapter<Owner> {
private Context context;
private int layoutResourceId;
private Owner data[] = null;
public OwnerAdapter(Context context, int textViewResourceId,Owner[] data) {
super(context, textViewResourceId, data);
this.context = context;
this.layoutResourceId = textViewResourceId;
this.data = data;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
OwnerHolder holder = null;
if(row == null)
{
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new OwnerHolder();
holder.tvFName = (TextView) row.findViewById(R.id.tvFirstName);
holder.tvLName = (TextView) row.findViewById(R.id.tvLastName);
holder.tvCId = (TextView) row.findViewById(R.id.tvCarID);
row.setTag(holder);
} else
{
holder = (OwnerHolder) row.getTag();
}
Owner item = data[position];
holder.tvFName.setText(item.getFirstName());
holder.tvLName.setText("Example");
holder.tvCId.setText("1");
return row;
}
static class OwnerHolder
{
TextView tvFName;
TextView tvLName;
TextView tvCId;
}
}
package com.mb.carlovers.asynctask;
import java.util.ArrayList;
import java.util.List;
import com.mb.carlovers.Car;
import android.os.AsyncTask;
public class CarAsyncTask extends AsyncTask<String, Void, List<Car>> {
private List<Car> item = null;
#Override
protected List<Car> doInBackground(String... params) {
item = new ArrayList<Car>();
item.add(new Car("Chevy","Caprice","2002"));
item.add(new Car("Chevy","Malibu","2014"));
item.add(new Car("Dodge","Stratus","2002"));
item.add(new Car("Saturn","L300","2004"));
return item;
}
#Override
protected void onPostExecute(List<Car> result) {
super.onPostExecute(result);
}
}
package com.mb.carlovers.asynctask;
import java.util.ArrayList;
import java.util.List;
import com.mb.carlovers.Owner;
import android.os.AsyncTask;
public class OnwerAsyncTask extends AsyncTask<String, Void, List<Owner>> {
private List<Owner> items = null;
#Override
protected List<Owner> doInBackground(String... params) {
try
{
items = new ArrayList<Owner>();
Owner own = new Owner();
own.setFirstName("John");
own.setLastName("Smith");
own.setCarId("1");
items.add(own);
Owner own1 = new Owner();
own1.setFirstName("Samantha");
own1.setLastName("Right");
own1.setCarId("2");
items.add(own1);
Owner own2 = new Owner();
own2.setFirstName("Regie");
own2.setLastName("Miller");
own2.setCarId("3");
items.add(own2);
Owner own3 = new Owner();
own3.setFirstName("Mark");
own3.setLastName("Adam");
own3.setCarId("4");
items.add(own3);
} catch(Exception ex)
{
ex.toString();
}
return items;
}
#Override
protected void onPostExecute(List<Owner> result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
}
// car_detail.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Car Detail Page" />
</LinearLayout>
// car_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<TextView
android:id="#+id/tvMake"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="" />
<TextView
android:id="#+id/tvModel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="" />
<TextView
android:id="#+id/tvYear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="" />
</LinearLayout>
//customize_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="#id/android:list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
<TextView
android:id="#id/android:empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No record to be displayed."
/>
</LinearLayout>
//Login.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".Login" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="User Name"
android:textSize="30sp"
android:layout_marginTop="10dp"
android:layout_gravity="center"
/>
<EditText
android:id="#+id/etUserName"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:ems="10"
android:layout_gravity="center"
android:layout_marginTop="10dp"
>
<requestFocus />
</EditText>
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Password"
android:textSize="30sp"
android:layout_marginTop="10dp"
android:layout_gravity="center"
/>
<EditText
android:id="#+id/etPassword"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:ems="10"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:inputType="textPassword" />
<Button
android:id="#+id/bLogin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_gravity="center"
android:text="Login" />
</LinearLayout>
//owner_detail.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<TextView
android:id="#+id/tvFirstName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="TextView" />
<TextView
android:id="#+id/tvLastName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="TextView" />
<TextView
android:id="#+id/tvCarID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="TextView" />
</LinearLayout>
// People.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight="1"
>
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Search by last name"
android:textSize="30sp"
android:layout_marginLeft="10dp"
android:layout_marginTop="15dp"
/>
<EditText
android:id="#+id/etByLastName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:inputType="textPersonName" >
<requestFocus />
</EditText>
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Search by car id"
android:textSize="30sp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10sp"
/>
<EditText
android:id="#+id/etCarID"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:layout_marginLeft="10dp"
android:layout_marginTop="10sp"
/>
<Spinner
android:id="#+id/spOption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="#array/spOptions"
/>
<TextView
android:id="#+id/tvErrorMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FF0000"
android:layout_marginTop="10dp"
android:text="" />
<Button
android:id="#+id/bSearch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="Button" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight="2"
>
<fragment
android:id="#+id/fOwnerDetail"
android:name="com.mb.carlovers.OwnerDetail"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
<fragment
android:id="#+id/fragment1"
android:name="com.mb.carlovers.CarDetail"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
/>
</LinearLayout>
</LinearLayout>
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setListAdapter(ownerAdapter);
}
}
Your code has a lot of problems:
1 Never call lifecycle methods on your own like you do in the OwnerDetail class with super.onActivityCreated(savedInstanceState);
2 Bundle values = getActivity().getIntent().getExtras(); ... values.getParcelableArray("test"); will normally fail because this piece of code will get the activity reference, get the Intent that started the activity and then try to find data passed in under the test key in that Intent. You don't pass such data to the People activity so there will be nothing to be found. You'd normally want to pass a Bundle containing the data at the moment of the creation of the fragment.
3 If you use the fragment in the xml layout you'll not be able to use a Bundle to pass data, instead you either add the fragment manually with transactions and then use a Bundle or you create a setter method in the fragment class and use that. So instead of Bundle data = new Bundle(); data.putParcelableArray("test", myOwners);, which does nothing, get a reference to your fragment and pass the myOwners array through a method.
4 Your AsyncTask will be pretty useless if you use them with .get() because the get() method will wait the AsyncTask to finish, blocking the UI tread as well. Instead you should just start the AsyncTask and then in the onPostExecute() pass the data around.
Here is an example with a simple method which will not change most of your code(which will happen if you manually add the fragments):
// where you start the owner asynctask
if(!searchByName.matches("")) {
OnwerAsyncTask asynTask = new OnwerAsyncTask(People.this);
asynTask.execute("");
}
//...
Then change the OnwerAsyncTask like this:
public class OnwerAsyncTask extends AsyncTask<String, Void, List<Owner>> {
private List<Owner> items = null;
private FragmentActivity mActivity;
public OnwerAsyncTask(FragmentActivity activity) {
mActivity = activity;
}
// doInBackground()...
#Override
protected void onPostExecute(List<Owner> result) {
//I'm assuming that items is the data you want to return, so
// find the OwnerDetail fragment and directly assign the data
OwnerDetail fragment = (OwnerDetail)mActivity.getSupportFragmentManager().findFragmentById(R.id.fOwnerDetail);
fragment.setData(); // to setData you'll pass the data you have in the AsyncTask
// the items list? or you transform that into an array?
}
and in the OwnerDetail fragment:
public class OwnerDetail extends ListFragment {
OwnerAdapter ownerAdapter = null;
public void setData() {
// update the adapter, create a new one etc.
}

Android custom listview row

I'm struggling with assigning my listview row more than one textview.
I want my row to have one textview for a person's name, one for address and one for age - but I'm not succeeding in doing so.
If someone could provide me with a simple example, that would be great.
Thanks!
Here's my custom ArrayAdapter
import java.util.ArrayList;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class MyAdapter extends BaseAdapter {
private LayoutInflater mInflater = null;
private ArrayList<Invoice> peopleList;
private final class ViewHolder {
TextView kidLabel;
TextView restLabel;
TextView fristLabel;
TextView amountLabel;
}
private ViewHolder mHolder = null;
public MyAdapter(Context context) {
Context mContext = context;
mInflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return peopleList.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
mHolder = new ViewHolder();
convertView = mInflater.inflate(R.layout.row, null);
convertView.setTag(mHolder);
} else {
mHolder = (ViewHolder) convertView.getTag();
}
mHolder.kidLabel = (TextView) convertView.findViewById(R.id.kidLabel);
mHolder.kidLabel.setText(peopleList.get(position).getKID());
mHolder.fristLabel = (TextView) convertView
.findViewById(R.id.fristLabel);
mHolder.fristLabel.setText(peopleList.get(position).getDueDate());
mHolder.restLabel = (TextView) convertView.findViewById(R.id.restLabel);
mHolder.restLabel.setText(peopleList.get(position).getDueAmount());
mHolder.amountLabel = (TextView) convertView
.findViewById(R.id.amountLabel);
mHolder.amountLabel.setText(peopleList.get(position).getDueAmount());
return convertView;
}
}
And Here's my custom row xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/RelativeLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="fill_parent"
android:layout_height="45dip"
android:src="#drawable/cellback" android:scaleType="fitXY"/>
<TextView
android:id="#+id/kidLabel"
android:layout_width="160dip"
android:layout_height="25dip"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:textSize="13dip" android:textColor="#333"/>
<TextView
android:id="#+id/fristLabel"
android:layout_width="160dip"
android:layout_height="20dip"
android:layout_marginTop="25dip"
android:textSize="11dip" android:textColor="#999"/>
<TextView
android:id="#+id/amountLabel"
android:layout_width="160dip"
android:layout_height="25dip"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:textSize="13dip" android:layout_marginLeft="160dip" android:gravity="right" android:textColor="#333"/>
<TextView
android:id="#+id/restLabel"
android:layout_width="160dip"
android:layout_height="20dip"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:textSize="11dip" android:layout_marginLeft="160dip" android:layout_marginTop="25dip" android:gravity="right" android:textColor="#999"/>
</RelativeLayout>
First,you should create a xml to describe what your list cell likes,called cell.xml,for example:
<?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="wrap_content"
android:orientation="vertical" android:background="#color/spink">
<TextView
android:id="#+id/name_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/address_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Address"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
Second,create a adapter.It helps your listview to show data:
public class MyAdapter extends BaseAdapter {
private LayoutInflater mInflater = null;
private ArrayList<People> peopleList;
private final class ViewHolder {
TextView nameTextView;
TextView addressTextView;
}
private ViewHolder mHolder = null;
public MyAdapter(Context context) {
mContext = context;
mInflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return peopleList.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
mHolder = new ViewHolder();
convertView = mInflater.inflate(R.layout.cell, null);
convertView.setTag(mHolder);
} else {
mHolder = (ViewHolder)convertView.getTag();
}
mHolder.nameTextView (TextView)convertView.findViewById(R.id.name_textView);
mHolder.nameTextView.setText(peopleList.get(position).getName());
mHolder.addressTextView = (TextView)convertView.findViewById(R.id.address_textView);
mHolder.addressTextView.setText(peopleList.get(position).getAddress());
return convertView;
}
}
Finally,when you want to show the data,do this in your activity:
listView.setAdapter(new MyAdapter());
hope it helps you.
You need to create a custom listview layout and a custom array adapter (I have also created a custom class to work with the layout).
An example of this is:
Custom class that works with the custom listview layout:
package id10778734.sceresini.week4.exercise3.views;
import id10778734.sceresini.week4.exercise3.R;
import id10778734.sceresini.week4.exercise3.Constants;
import id10778734.sceresini.week4.exercise3.tasks.Task;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class TaskListItem extends LinearLayout {
private Task mTask;
private ImageView mEmailImageView;
private ImageView mPriorityImageView;
private TextView mTaskNameTextView;
private TextView mTaskResponsibleTextView;
private ImageView mDeleteImageView;
public TaskListItem (Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public void onFinishInflate() {
super.onFinishInflate();
mEmailImageView = (ImageView) findViewById(R.id.list_row_layout_email_button);
mPriorityImageView = (ImageView) findViewById(R.id.list_row_layout_priority_icon);
mTaskNameTextView = (TextView) findViewById(R.id.list_row_layout_task_name);
mTaskResponsibleTextView = (TextView) findViewById(R.id.list_row_layout_responsible);
mDeleteImageView = (ImageView) findViewById(R.id.list_row_layout_delete_button);
}
public void setTask (Task task) {
mTask = task;
mEmailImageView.setTag(task);
switch (task.getPriority()) {
case Constants.LOW:
mPriorityImageView.setImageResource(R.drawable.low);
break;
case Constants.MEDIUM:
mPriorityImageView.setImageResource(R.drawable.medium);
break;
case Constants.HIGH:
mPriorityImageView.setImageResource(R.drawable.high);
break;
}
mTaskNameTextView.setText(task.getName());
mTaskResponsibleTextView.setText(task.getResponsible());
mDeleteImageView.setTag(task);
}
public Task getTask () {
return mTask;
}
public ImageView getDeleteImageView () {
return mDeleteImageView;
}
public ImageView getEmailImageView () {
return mEmailImageView;
}
}
the custom layout xml file:
<?xml version="1.0" encoding="UTF-8"?>
<id10778734.sceresini.week4.exercise3.views.TaskListItem
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dip" >
<ImageView
android:id="#+id/list_row_layout_email_button"
android:layout_width="36dip"
android:layout_height="36dip"
android:layout_gravity="center_vertical"
android:layout_marginLeft="4dip"
android:layout_marginRight="5dip"
android:contentDescription="#string/list_row_email_icon_description"
android:src="#android:drawable/ic_dialog_email" />
<ImageView
android:id="#+id/list_row_layout_priority_icon"
android:layout_width="24dip"
android:layout_height="24dip"
android:layout_gravity="center_vertical"
android:layout_marginLeft="4dip"
android:layout_marginRight="10dip"
android:contentDescription="#string/view_task_priority_icon_description" />
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical" >
<TextView
android:id="#+id/list_row_layout_task_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_toLeftOf="#+id/list_row_layout_responsible"
android:paddingRight="5dip"
android:textAppearance="#style/list_row_task_name" />
<TextView
android:id="#id/list_row_layout_responsible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="#+id/list_row_layout_delete_button"
android:maxWidth="100dip"
android:textAppearance="#style/list_row_task_responsible" />
<ImageView
android:id="#id/list_row_layout_delete_button"
android:layout_width="36dip"
android:layout_height="36dip"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginLeft="5dip"
android:layout_marginRight="5dip"
android:contentDescription="#string/delete_task_icon_description"
android:src="#drawable/task_delete" />
</RelativeLayout>
</id10778734.sceresini.week4.exercise3.views.TaskListItem>
And the custom array adapter:
package id10778734.sceresini.week4.exercise3;
import id10778734.sceresini.week4.exercise3.R;
import id10778734.sceresini.week4.exercise3.tasks.Task;
import id10778734.sceresini.week4.exercise3.views.TaskListItem;
import java.util.ArrayList;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
public class TaskListAdapter extends BaseAdapter
{
private ArrayList<Task> mTasks;
private Context mContext;
private AlertDialog unsavedChangesDialog;
private TaskManagerApplication mApp;
public TaskListAdapter(Context context, ArrayList<Task> tasks) {
super();
mApp = (TaskManagerApplication) context.getApplicationContext();
mContext = context;
mTasks = tasks;
}
#Override
public int getCount()
{
return mTasks.size();
}
#Override
public Task getItem(int position)
{
return (null == mTasks) ? null : mTasks.get(position);
}
#Override
public long getItemId(int position)
{
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
TaskListItem tli;
if (null == convertView)
{
tli = (TaskListItem) View.inflate(mContext, R.layout.list_row_layout, null);
} else
{
tli = (TaskListItem) convertView;
}
tli.setTask(mTasks.get(position));
tli.getEmailImageView().setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v)
{
emailTask(v);
}
});
tli.getDeleteImageView().setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v)
{
deleteTask(v);
}
});
return tli;
}
/**
* deleteTask() prompts the user with an alert dialog and presents them with
* the option to continue with the delete request or to cancel the request.
* Upon confirmation, the selected Task object which is retrieved from the
* deleteTaskIcon tag, will be removed from the list of currentTasks.
*
* #param v
*/
protected void deleteTask(View v)
{
final Task t = (Task) v.getTag();
String alertMessage = String.format(mContext.getString(R.string.delete_task_message), t.getName());
unsavedChangesDialog = new AlertDialog.Builder(mContext).setTitle(R.string.delete_task_title).setMessage(alertMessage)
// Delete the task and refresh the adapter.
.setPositiveButton(R.string.delete_task_delete, new AlertDialog.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1)
{
// Remove task from array list
mTasks.remove(t);
// Remove task from Database
mApp.deleteTask(t);
// Display toast message stating the task was deleted
mApp.displayToast(Constants.TASK_DELETED);
// Update listView with modified adapter
forceReload();
}
})
// Cancel the delete request and do nothing.
.setNegativeButton(R.string.delete_task_cancel, new AlertDialog.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1)
{
unsavedChangesDialog.cancel();
}
}).create();
unsavedChangesDialog.show();
}
/**
* emailTask() populates the selected task into an intent which allows the
* user to select a client to send the task. This is formatted for email
* clients.
*
* #param v
*/
protected void emailTask(View v)
{
// Retrieve the task that is allocated to this RowView
final Task t = (Task) v.getTag();
// Instantiate the intent that will be used to call the email client
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
// Variables/Arrays to hold email attributes
String[] emailRecipients = { mContext.getString(R.string.email_task_to_email) };
String emailType = mContext.getString(R.string.email_task_type);
String emailTitle = mContext.getString(R.string.email_task_title);
String emailSubject = String.format(mContext.getString(R.string.email_task_subject), t.getName());
String emailMessage = String.format(mContext.getString(R.string.email_task_message), t.getResponsible(), t.getName(), mContext.getString(t.getPriorityStringId()));
// Add the email attributes to the intent
emailIntent.setType(emailType);
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, emailRecipients);
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, emailSubject);
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, emailMessage);
// Start intent
mContext.startActivity(Intent.createChooser(emailIntent, emailTitle));
}
/**
* Refreshes the ListView with the modified dataset.
*/
public void forceReload()
{
notifyDataSetChanged();
}
}

need help for on click listener for android custom ListView

my app has custom ListView, each row contains checkbox ,edit text and 2 buttons. In the main xml layout file i have 1 submit button and listView. i want that, when i click on submit button, i should get all checked row position.I am new to android programming ,so plz help me my code is not working here is my code:
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button android:layout_height="wrap_content"
android:text="#string/button_submit"
android:layout_width="wrap_content"
android:id="#+id/main_submit_button" android:onClick="#string/button_submit"></Button>
<ListView
android:id="#+id/list_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
items.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout android:layout_height="wrap_content"
android:layout_width="fill_parent">
<TextView
android:layout_height="wrap_content"
android:layout_width="fill_parent" android:layout_weight="1"
android:id="#+id/items_name"
android:gravity="left"
android:textStyle="bold" />
<CheckBox android:id="#+id/items_check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
/>
</LinearLayout>
<LinearLayout android:layout_height="wrap_content"
android:layout_width="fill_parent">
<Button android:id="#+id/items_add_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:text="#string/text_switcher_plus" />
<EditText android:digits="10"
android:textStyle="bold" android:gravity="left"
android:id="#+id/items_plates" android:layout_height="wrap_content"
android:layout_width="90dp"></EditText>
<Button android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/items_minus_button"
android:text="#string/text_switcher_minus"
android:gravity="right"
/>
</LinearLayout>
</LinearLayout>
VegmenuActivity
package com.sagar.resmenu;
import java.util.ArrayList;
import java.util.Arrays;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
// reference:http://pareshnmayani.wordpress.com/tag/android-custom-listview-example
public class VegmenuActivity extends Activity implements OnItemClickListener{
//dynamic array that contains names of items
private ArrayList<String> items = new ArrayList<String>
(Arrays.asList("Veg pulav", "Pav bhaji", "Panir tikka", "veg kolhapuri",
"Coconut Rice", "Curd rice", "Mint Pulao",
"Banana Custard","Basundi", "Cheese potato Tikkis",
"Dum aloo"));
private ArrayList<Integer> counter = new ArrayList<Integer>
(Arrays.asList(0, 0,0, 0, 0,0, 0,0, 0,0,0));
private SparseBooleanArray a;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final ListView lv =(ListView)findViewById(R.id.list_view);
// lv.setOnClickListener(null);
MyAdapter adapter = new MyAdapter(getApplicationContext(),items,counter);
lv.setAdapter(adapter);
lv.setItemsCanFocus(false);
lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
Button submit1;
submit1 = (Button)findViewById(R.id.main_submit_button);
submit1.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
a = new SparseBooleanArray();
a.clear();
a = lv.getCheckedItemPositions();
int len = items.size();
for (int i = 0; i < len; i++)
{
if(a.valueAt(i) == true)
Log.d("Returned ", String.valueOf(a.valueAt(i)));
}
}
});
}
//private OnItemClickListener selectCat = new OnItemClickListener();
public void onItemClick(AdapterView<?> a, View v, int positon, long id) {
// TODO Auto-generated method stub
}
}
MyAdapter.java
package com.sagar.resmenu;
import java.util.ArrayList;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextSwitcher;
import android.widget.TextView;
public class MyAdapter extends BaseAdapter implements OnClickListener{
private LayoutInflater inflater;
private ArrayList<String> data;
VegmenuActivity m;
private ArrayList<Integer> counter;
public MyAdapter(Context context, ArrayList<String> data,ArrayList<Integer> counter) {
// TODO Auto-generated constructor stub
super();
// Caches the LayoutInflater for quicker use
this.inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// Sets the events data
this.data= data;
this.counter=counter;
}
public int getCount() {
return this.data.size();
//return this.counter.size();
}
public String getItem(int position) throws IndexOutOfBoundsException{
return null;
}
public long getItemId(int position) throws IndexOutOfBoundsException{
return 0;
}
public int getViewTypeCount(){
return 1;
}
public static class ViewHolder
{
TextView items_name;
CheckBox items_check ;
Button items_plus_button;
Button items_minus_button;
EditText plates;
}
public View getView(int position, View convertView, ViewGroup parent){
//String myText = getItem(position);
ViewHolder holder;
if(convertView == null){ // If the View is not cached
// Inflates the Common View from XML file
holder = new ViewHolder();
convertView = this.inflater.inflate(R.layout.items,parent,false);
holder.items_name = (TextView) convertView.findViewById(R.id.items_name);
holder.plates = (EditText) convertView.findViewById(R.id.items_plates);
holder.items_check = (CheckBox) convertView.findViewById(R.id.items_check);
convertView.setTag(holder);
}
else
holder=(ViewHolder)convertView.getTag();
holder.items_name.setText(data.get(position));
holder.plates.setText(String.valueOf(counter.get(position)));
return convertView;
}
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
}
}
when I need check boxes inside listview, I often code as following:
MyAdapter.java:
- Declare an boolean array to mark which item is checked/unchecked:
....
boolean[] checked;
...
inside constructor:
checked = new boolean[data.size()];
- Inside getView()
{
.....
holder.items_check.setChecked(checked[position]);
holder.items_check.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
checked[position] = isChecked;
}
});
.....
- And method to get all checked items:
boolean[] getCheckedItems() {
return checked;
}
That's !
Could it be that your getItem and getItemId only return null and 1? These methods need to return the correct data for this to work I believe. getItem would need to be:
String getItem(int position)
{
return data.get(position);
}
and getItemId would simply return position instead of 0:
String getItemId(int position)
{
return position;
}

Categories

Resources