Android Spinner: app crashes onItemSelected [closed] - android

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I came up with problem integrating setting title to my custom spinner. After click on any item crashes with this error.
08-04 02:48:39.490 16956-16956/com.example.ilija.festivalapp_makedox E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.ilija.festivalapp_makedox, PID: 16956
java.lang.NullPointerException
at com.example.ilija.festivalapp_makedox.CustomSpinner$1.onItemSelected(CustomSpinner.java:98)
at com.example.ilija.festivalapp_makedox.SpinnerPlus.setSelection(SpinnerPlus.java:21)
at android.widget.Spinner$DropdownPopup$1.onItemClick(Spinner.java:1042)
at android.widget.AdapterView.performItemClick(AdapterView.java:299)
at android.widget.AbsListView.performItemClick(AbsListView.java:1282)
at android.widget.ListView.performItemClick(ListView.java:4450)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3174)
at android.widget.AbsListView$3.run(AbsListView.java:3925)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5872)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:674)
at dalvik.system.NativeStart.main(Native Method)
CustomSpinner.java:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_spinner);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle("Movies");
setSupportActionBar(toolbar);
activity = this;
SpinnerPlus SpinnerExample = (SpinnerPlus) findViewById(R.id.spinner);
SpinnerPlus SpinnerExample1 = (SpinnerPlus) findViewById(R.id.spinner1);
SpinnerPlus SpinnerExample2 = (SpinnerPlus) findViewById(R.id.spinner2);
SpinnerPlus SpinnerExample3 = (SpinnerPlus) findViewById(R.id.spinner3);
SpinnerPlus SpinnerExampleTest = (SpinnerPlus) findViewById(R.id.spinnerTest);
/* Spinner SpinnerExampleTest = (Spinner) findViewById(R.id.spinnerTest);
Spinner SpinnerExampleTest1 = (Spinner) findViewById(R.id.spinner1Test);
Spinner SpinnerExampleTest2 = (Spinner) findViewById(R.id.spinner2Test);
Spinner SpinnerExampleTest3 = (Spinner) findViewById(R.id.spinner3Test);*/
output = (TextView)findViewById(R.id.output);
setListData();
setListData1();
setListData2();
setListData3();
setListDataTest();
/* setListData1Test();
setListData2Test();
setListData3Test();*/
Resources res = getResources();
adapter = new CustomAdapter(activity,R.layout.spinner_rows,CustomListViewValuesArr,res);
adapter1 = new CustomAdapter(activity,R.layout.spinner_rows,CustomListViewValuesArr1,res);
adapter2 = new CustomAdapter(activity,R.layout.spinner_rows,CustomListViewValuesArr2,res);
adapter3 = new CustomAdapter(activity,R.layout.spinner_rows,CustomListViewValuesArr3,res);
adapterTest = new CustomAdapter(activity,R.layout.spinner_rows,CustomListViewValuesArrTest,res);
/*adapter1Test = new CustomAdapter(activity,R.layout.spinner_rows,CustomListViewValuesArr1Test,res);
adapter2Test = new CustomAdapter(activity,R.layout.spinner_rows,CustomListViewValuesArr2Test,res);
adapter3Test = new CustomAdapter(activity,R.layout.spinner_rows,CustomListViewValuesArr3Test,res);*/
adapter.setDropDownViewResource(R.layout.spinner_rows);
SpinnerExample.setPrompt("Select your favorite Planet!");
SpinnerExample.setAdapter(
new NothingSelectedSpinnerAdapter(
adapter,
R.layout.contact_spinner_row_nothing_selected,
// R.layout.contact_spinner_nothing_selected_dropdown, // Optional
this));
SpinnerExample.setOnItemSelectedEvenIfUnchangedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// i++; //Avoid fist time oppening the OnClick start new intent. First time is for set pic of the first element in the list.
String Movie = ((TextView) view.findViewById(R.id.movieName)).getText().toString();
// if(i>=1){
Intent intent = new Intent(CustomSpinner.this, MovieTrailer.class);
if(position==0) {
intent.putExtra("Cartoons","10");
} else if(position==1) {
intent.putExtra("Cartoons","11");
} else if(position==2) {
intent.putExtra("Cartoons","12");
} else if(position==3) {
intent.putExtra("Cartoons","13");
} else if(position==4) {
intent.putExtra("Cartoons","14");
} else if(position==5) {
intent.putExtra("Cartoons","15");
} else if(position==6) {
intent.putExtra("Cartoons","16");
} else if(position==7) {
intent.putExtra("Cartoons","17");
} else if(position==8) {
intent.putExtra("Cartoons","18");
}
startActivity(intent);
//}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
SpinnerExample1.setAdapter(adapter1);
SpinnerExample1.setOnItemSelectedEvenIfUnchangedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// i++; //Avoid fist time oppening the OnClick start new intent. First time is for set pic of the first element in the list.
String Movie = ((TextView) view.findViewById(R.id.movieName)).getText().toString();
// if(i>2){
Intent intent = new Intent(CustomSpinner.this, MovieTrailer.class);
if(position==0) {
intent.putExtra("Cartoons","20");
} else if(position==1) {
intent.putExtra("Cartoons","21");
} else if(position==2) {
intent.putExtra("Cartoons","22");
} else if(position==3) {
intent.putExtra("Cartoons","23");
} else if(position==4) {
intent.putExtra("Cartoons","24");
} else if(position==5) {
intent.putExtra("Cartoons","25");
} else if(position==6) {
intent.putExtra("Cartoons","26");
} else if(position==7) {
intent.putExtra("Cartoons","27");
} else if(position==8) {
intent.putExtra("Cartoons","28");
}
startActivity(intent);
// }
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
NothingSelectedSpinnerAdapter.java
package com.example.ilija.festivalapp_makedox;
import android.content.Context;
import android.database.DataSetObserver;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.SpinnerAdapter;
/**
* Decorator Adapter to allow a Spinner to show a 'Nothing Selected...' initially
* displayed instead of the first choice in the Adapter.
*/
public class NothingSelectedSpinnerAdapter implements SpinnerAdapter, ListAdapter {
protected static final int EXTRA = 1;
protected SpinnerAdapter adapter;
protected Context context;
protected int nothingSelectedLayout;
protected int nothingSelectedDropdownLayout;
protected LayoutInflater layoutInflater;
/**
* Use this constructor to have NO 'Select One...' item, instead use
* the standard prompt or nothing at all.
* #param spinnerAdapter wrapped Adapter.
* #param nothingSelectedLayout layout for nothing selected, perhaps
* you want text grayed out like a prompt...
* #param context
*/
public NothingSelectedSpinnerAdapter(
SpinnerAdapter spinnerAdapter,
int nothingSelectedLayout, Context context) {
this(spinnerAdapter, nothingSelectedLayout, -1, context);
}
/**
* Use this constructor to Define your 'Select One...' layout as the first
* row in the returned choices.
* If you do this, you probably don't want a prompt on your spinner or it'll
* have two 'Select' rows.
* #param spinnerAdapter wrapped Adapter. Should probably return false for isEnabled(0)
* #param nothingSelectedLayout layout for nothing selected, perhaps you want
* text grayed out like a prompt...
* #param nothingSelectedDropdownLayout layout for your 'Select an Item...' in
* the dropdown.
* #param context
*/
public NothingSelectedSpinnerAdapter(SpinnerAdapter spinnerAdapter,
int nothingSelectedLayout, int nothingSelectedDropdownLayout, Context context) {
this.adapter = spinnerAdapter;
this.context = context;
this.nothingSelectedLayout = nothingSelectedLayout;
this.nothingSelectedDropdownLayout = nothingSelectedDropdownLayout;
layoutInflater = LayoutInflater.from(context);
}
#Override
public final View getView(int position, View convertView, ViewGroup parent) {
// This provides the View for the Selected Item in the Spinner, not
// the dropdown (unless dropdownView is not set).
if (position == 0) {
return getNothingSelectedView(parent);
}
return adapter.getView(position - EXTRA, null, parent); // Could re-use
// the convertView if possible.
}
/**
* View to show in Spinner with Nothing Selected
* Override this to do something dynamic... e.g. "37 Options Found"
* #param parent
* #return
*/
protected View getNothingSelectedView(ViewGroup parent) {
return layoutInflater.inflate(nothingSelectedLayout, parent, false);
}
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
// Android BUG! http://code.google.com/p/android/issues/detail?id=17128 -
// Spinner does not support multiple view types
if (position == 0) {
return nothingSelectedDropdownLayout == -1 ?
new View(context) :
getNothingSelectedDropdownView(parent);
}
// Could re-use the convertView if possible, use setTag...
return adapter.getDropDownView(position - EXTRA, null, parent);
}
/**
* Override this to do something dynamic... For example, "Pick your favorite
* of these 37".
* #param parent
* #return
*/
protected View getNothingSelectedDropdownView(ViewGroup parent) {
return layoutInflater.inflate(nothingSelectedDropdownLayout, parent, false);
}
#Override
public int getCount() {
int count = adapter.getCount();
return count == 0 ? 0 : count + EXTRA;
}
#Override
public Object getItem(int position) {
return position == 0 ? null : adapter.getItem(position - EXTRA);
}
#Override
public int getItemViewType(int position) {
return 0;
}
#Override
public int getViewTypeCount() {
return 1;
}
#Override
public long getItemId(int position) {
return position >= EXTRA ? adapter.getItemId(position - EXTRA) : position - EXTRA;
}
#Override
public boolean hasStableIds() {
return adapter.hasStableIds();
}
#Override
public boolean isEmpty() {
return adapter.isEmpty();
}
#Override
public void registerDataSetObserver(DataSetObserver observer) {
adapter.registerDataSetObserver(observer);
}
#Override
public void unregisterDataSetObserver(DataSetObserver observer) {
adapter.unregisterDataSetObserver(observer);
}
#Override
public boolean areAllItemsEnabled() {
return false;
}
#Override
public boolean isEnabled(int position) {
return position != 0; // Don't allow the 'nothing selected'
// item to be picked.
}
}
SpinnerPlus.java:
import android.content.Context;
import android.util.AttributeSet;
import android.widget.AdapterView;
import android.widget.Spinner;
import java.lang.reflect.Field;
public class SpinnerPlus extends Spinner {
AdapterView.OnItemSelectedListener listener;
public SpinnerPlus(Context context, AttributeSet attrs) {
super(context,attrs);
}
#Override
public void setSelection(int position) {
super.setSelection(position);
if (listener != null)
listener.onItemSelected(this, getSelectedView(), position, 0);
}
public void setOnItemSelectedEvenIfUnchangedListener(
AdapterView.OnItemSelectedListener listener) {
this.listener = listener;
}
}
CustomAdapter.java
package com.example.ilija.festivalapp_makedox;
import android.app.Activity;
import android.graphics.Color;
import android.view.View;
import android.view.ViewGroup;
import android.content.Context;
import android.content.res.Resources;
import android.view.LayoutInflater;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.util.ArrayList;
/**
* Created by ilija on 15-Jul-16.
*/
public class CustomAdapter extends ArrayAdapter<String>{
private Activity activity;
private ArrayList data;
public Resources res;
SpinnerModel tempValues=null;
LayoutInflater inflater;
public CustomAdapter(
CustomSpinner activitySpinner,
int textViewResourceId,
ArrayList objects,
Resources resLocal
) {
super(activitySpinner, textViewResourceId, objects);
activity = activitySpinner;
data = objects;
res=resLocal;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public View getDropDownView(int position, View convertView, ViewGroup parent){
return getCustomView(position,convertView,parent);
}
public View getView(int position, View convertView, ViewGroup parent){
return getCustomView(position,convertView,parent);
}
public View getCustomView(int position, View convertView, ViewGroup parent){
View row = inflater.inflate(R.layout.spinner_rows, parent, false);
tempValues = null;
tempValues = (SpinnerModel) data.get(position);
TextView label = (TextView)row.findViewById(R.id.movieName);
ImageView image = (ImageView)row.findViewById(R.id.imageSpinner);
RelativeLayout backgorund = (RelativeLayout)row.findViewById(R.id.spinnerBackground);
label.setText(tempValues.getMovieName());
image.setImageResource(res.getIdentifier("com.example.ilija.festivalapp_makedox:drawable/"+tempValues.getImage(),null,null));
//backgorund.setBackgroundColor(tempValues.getBackground());
return row;
}
}
activity_custom_spinner.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:agendaCalendar="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainScreen">
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<!--tools:context=".MainScreen"-->
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:fitsSystemWindows="true"
tools:context=".MainScreen">
<android.support.design.widget.AppBarLayout android:layout_height="wrap_content"
android:layout_width="match_parent" android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar android:id="#+id/toolbar"
android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary" app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<ImageView
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginTop="55dp"
android:id="#+id/imageView2"
android:layout_alignParentTop="true"
android:background="#drawable/makecover"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"/>
<ScrollView
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="155dp"
android:layout_marginBottom="10dp"
android:fillViewport="true"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="11dp"
android:layout_marginRight="11dp"
android:orientation="vertical"
>
<TextView
android:id="#+id/ico"
android:text="SELECTIONS:"
android:paddingTop="10dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="1dp" />
<TextView
android:id="#+id/ico1"
android:text="INTERNATIONAL COMPETITION"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="1dp"
android:paddingTop="5dp"/>
<com.example.ilija.festivalapp_makedox.SpinnerPlus
android:id="#+id/spinner"
android:background="#color/main_competition"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/ico2"
android:text="NEWCOMERS COMPETITION"
android:paddingLeft="1dp"
android:paddingTop="5dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<!-- <com.example.ilija.festivalapp_makedox.SpinnerPlus
android:id="#+id/spinner1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>-->
<com.example.ilija.festivalapp_makedox.SpinnerPlus
android:id="#+id/spinner1"
android:background="#color/newcomers"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="#+id/ico3"
android:text="FOCUS RUSSIA"
android:paddingLeft="1dp"
android:paddingTop="5dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<com.example.ilija.festivalapp_makedox.SpinnerPlus
android:id="#+id/spinner2"
android:background="#color/russian"
android:spinnerMode="dropdown"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/ico4"
android:text="SHORT DOX"
android:paddingLeft="1dp"
android:paddingTop="5dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<com.example.ilija.festivalapp_makedox.SpinnerPlus
android:id="#+id/spinner3"
android:background="#color/short1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/spinnerTesttxt"
android:text="STUDENT DOX"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="1dp"
android:paddingTop="5dp"/>
<com.example.ilija.festivalapp_makedox.SpinnerPlus
android:id="#+id/spinnerTest"
android:background="#color/student"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<!--<TextView
android:id="#+id/ico2spinnerTest"
android:text="ActionSpinnerTest:"
android:paddingLeft="10dp"
android:paddingTop="5dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<Spinner
android:id="#+id/spinner1Test"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/ico3spinnerTest"
android:text="HorrorspinnerTest:"
android:paddingLeft="10dp"
android:paddingTop="5dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<Spinner
android:id="#+id/spinner2Test"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/ico4spinnerTest"
android:text="CartoonspinnerTest:"
android:paddingLeft="10dp"
android:paddingTop="5dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<Spinner
android:id="#+id/spinner3Test"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>-->
</LinearLayout>
</ScrollView>
<include layout="#layout/content_custom_spinner" />
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView android:id="#+id/nav_view"
android:layout_width="wrap_content" android:layout_height="match_parent"
android:layout_gravity="start" android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main" app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
</RelativeLayout>

May be ((TextView) view.findViewById(R.id.movieName)).getText().toString(); is null. Take your String from ListViewValues
SpinnerExample.setOnItemSelectedEvenIfUnchangedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// i++; //Avoid fist time oppening the OnClick start new intent. First time is for set pic of the first element in the list.
String Movie = (String) CustomListViewValuesArr1.get(postion)
// if(i>=1){
Intent intent = new Intent(CustomSpinner.this, MovieTrailer.class);
if(position==0) {
intent.putExtra("Cartoons","10");
} else if(position==1) {
intent.putExtra("Cartoons","11");
} else if(position==2) {
intent.putExtra("Cartoons","12");
} else if(position==3) {
intent.putExtra("Cartoons","13");
} else if(position==4) {
intent.putExtra("Cartoons","14");
} else if(position==5) {
intent.putExtra("Cartoons","15");
} else if(position==6) {
intent.putExtra("Cartoons","16");
} else if(position==7) {
intent.putExtra("Cartoons","17");
} else if(position==8) {
intent.putExtra("Cartoons","18");
}
startActivity(intent);
//}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});

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
}
});

Spinner with custom drop-down view not triggering onItemSelected()

I have a Spinner that uses a custom adapter where the getDropDownView() is overridden. Each item in the custom drop-down view is made up of a TextView and a Button.
But, when I run my code, the spinner drop-down items display fine, but clicking them does nothing. The spinner drop-down remains open and spinner.onItemSelected() is not triggered.
drop_down_item.xml
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/dropdown_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:singleLine="true" />
<Button
android:id="#+id/dropdown_button"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_alignParentRight="true"
android:text="Remove"/>
</RelativeLayout>
Custom adapter code
public View getDropDownView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.drop_down_item, parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.dropdown_text);
textView.setText(mValues.get(position));
Button buttonView = (Button) rowView.findViewById(R.id.dropdown_button));
return rowView;
}
I create my spinner and adapter with this code:
spinner = (Spinner) findViewById(R.id.my_spinner);
MyAdapter adapter = new MyAdapter(getViewContext(), R.layout.spinner_item, values);
adapter.setDropDownViewResource(R.layout.drop_down_item);
spinner.setAdapter(adapter);
...
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
// Do something here - but this never runs
}
});
So I don't know why onItemSelected() is no longer called?
I was wondering if I need to put a click listener on the drop-down TextView which should in turn trigger onItemSelected() using maybe spinner.setSelection(pos)?
The Events is basically a interface that Activity implements to recieve the callBack by clicking on the LinearLayout of the DropDown View of Spinner.
public class MyArrayAdapter extends BaseAdapter {
String[] values;
int CustomResource;
Context context;
Events events;
public MyArrayAdapter(Context baseContext, int customspinnerview,
String[] stringArray, Events events) {
values = stringArray;
context = baseContext;
this.events = events;
CustomResource = customspinnerview;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return values.length;
}
#Override
public Object getItem(int position) {
if (position < values.length)
return values[position];
else {
return null;
}
}
#Override
public View getView(final int position, final View convertView,
ViewGroup parent) {
View rowView = convertView;
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (rowView == null) {
rowView = inflater.inflate(CustomResource, parent, false);
}
TextView textView = (TextView) rowView.findViewById(R.id.dropdown_text);
textView.setText(values[position]);
Button button = (Button) rowView.findViewById(R.id.Button_text);
return rowView;
}
#Override
public View getDropDownView(final int position, View convertView,
ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = convertView;`enter code here`
if (rowView == null) {
rowView = inflater.inflate(CustomResource, parent, false);
}
final LinearLayout parentRelative = (LinearLayout) rowView
.findViewById(R.id.parent);
final TextView textView = (TextView) rowView
.findViewById(R.id.dropdown_text);
textView.setText(values[position]);
Button button = (Button) rowView.findViewById(R.id.Button_text);
rowView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
events.onItemSelectedLister(
(AdapterView<?>) parentRelative.getParent(),
parentRelative, position, (long) 0);
}
});
// Button buttonView = (Button)
// rowView.findViewById(R.id.dropdown_button);
return rowView;
}
Events Inteface Its a interface that the Activity implement in order to recieve the callbacks from the Adapter.
import android.view.View;
import android.widget.AdapterView;
public interface Events {
public void onItemSelectedLister(AdapterView<?> parent, View view,
int position, long id);
}
Activity Implementation.
onItemSelected Implementation is the place where you can do your task.....
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.annotation.TargetApi;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Spinner;
import com.example.adapter.MyArrayAdapter;
public class MainActivity extends Activity implements Events {
Spinner spinner;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
spinner = (Spinner) findViewById(R.id.spinner);
spinner.setAdapter(new MyArrayAdapter(getBaseContext(),
R.layout.customspinnerview, getResources().getStringArray(
R.array.values), this));
}
#Override
public void onItemSelectedLister(AdapterView<?> parent, View view,
final int position, long id) {
//perform your Task.......
Method method;
try {
method = Spinner.class.getDeclaredMethod("onDetachedFromWindow");
method.setAccessible(true);
try {
method.invoke(spinner);
} catch (IllegalAccessException | IllegalArgumentException
| InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
spinner.post(new Runnable() {
#Override
public void run() {
spinner.setSelection(position);
spinner.setSelected(true);
((MyArrayAdapter) spinner.getAdapter()).notifyDataSetChanged();
}
});
}
}
Activity xml File for setContentView
<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.customspinner.MainActivity" >
<Spinner
android:id="#+id/spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</Spinner>
</RelativeLayout>
Spinner View which is passed to Adapter as layout file.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#99000000"
android:id="#+id/parent"
android:orientation="horizontal">
<TextView
android:id="#+id/dropdown_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="#+id/Button_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="remove"/>
</LinearLayout>
the Code works perfectly fine :) .I have the code perfectly running.
Solution is to set android:focusable="false" in the layout for both the TextView and the Button.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/dropdown_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:focusable="false"
android:singleLine="true" />
<Button
android:id="#+id/dropdown_button"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_alignParentRight="true"
android:focusable="false"
android:text="Remove"/>
</RelativeLayout>
Alternatively can also do this in the code:
textView.setFocusable(false);
buttonView.setFocusable(false);
Found the answer here. This works because the Spinner implementation only allows one focusable item in the view. That's why I wasn't able to select the item.

Android: ListView headers lost when scrolling

So I have the following view
list_view_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layoutSessionItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/lblGroupDate"
style="#style/CustomText.GrayTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</TextView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/lblCourseCode"
style="#style/CustomText.GrayText"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/lblSessionCode"
style="#style/CustomText.GrayText"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</RelativeLayout>
So basically I get the following data from the database:
COURSE_CODE
SESSION_CODE
SESSION_DATE
I need to group the ListView items by SESSION_DATE, what I do is I keep a variable called "PreviousDate" and I compare it to the current SESSION_DATE, if it's different then I enable the header with the ID: "lblGroupDate" if the dates are the same I Hide "lblGroupDate".
Here's my Adapter:
public class SessionListAdapter extends BaseAdapter {
private Date PreviousDate = new Date();
static class ViewHolder {
TextView lblGroupDate;
TextView lblCourseCode;
TextView lblSessionCode;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mLayoutInflater.inflate(R.layout.list_view_item, null);
holder = new ViewHolder();
holder.lblGroupDate = (TextView) convertView.findViewById(R.id.lblGroupDate);
holder.lblCourseCode = (TextView) convertView.findViewById(R.id.lblCourseCode);
holder.lblSessionCode = (TextView) convertView.findViewById(R.id.lblSessionCode);
} else {
holder = (ViewHolder)convertView.getTag();
}
SessionData session = (SessionData) getItem(position);
if(session != null) {
Date sessionDate = session.SESSION_DATE;
if (!mPrevDate.equals(sessionDate)) {
PreviousDate = sessionDate;
// HIDE GROUP HEADER
holder.lblGroupDate.setVisibility(View.GONE);
}
else {
// SHOW GROUP HEADER
holder.lblGroupDate.setVisibility(View.VISIBLE);
}
holder.lblCourseCode.setText(session.COURSE_CODE);
holder.lblSessionCode.setText(session.SESSION_CODE);
}
}
}
Here's the PROBLEM:
Lets say I have 20 records, when I scroll down and then scroll up again the rows that had the Group Header (lblGroupDate) enabled get shifted up without a header, it's the header was shifted to the next 3 rows. Why is this happening?
It's happening because getView() can be called at anytime and out-of-order from your data-set. You need to create a data-set that the adapter can be backed by. Just sorting your adapter out. Will update answer with code in a moment.
SessionListAdapter.java
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import android.content.Context;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class SessionListAdapter extends BaseAdapter
{
private static final int TYPE_GROUP = 0;
private static final int TYPE_SESSION = 1;
private static final int MAX_TYPES = 2;
private final LayoutInflater mLayoutInflater;
private ArrayList<SessionViewData> mData;
public SessionListAdapter(Context context, List<SessionData> sessionData)
{
mLayoutInflater = LayoutInflater.from(context);
updateSessionViewData(sessionData);
}
public void updateSessionViewData(List<SessionData> sessionData)
{
Date previousDate = new Date();
ArrayList<SessionViewData> data = new ArrayList<SessionViewData>();
for(SessionData session: sessionData){
if(!previousDate.equals(session.SESSION_DATE)){
data.add(new SessionViewData(TYPE_GROUP, session));
previousDate = session.SESSION_DATE;
}
data.add(new SessionViewData(TYPE_SESSION, session));
}
mData = data;
notifyDataSetChanged();
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
SessionViewData data = mData.get(position);
if(convertView == null){
final int layoutId;
switch(data.type){
case TYPE_GROUP: layoutId = R.layout.list_session_group; break;
case TYPE_SESSION: layoutId = R.layout.list_session_item; break;
default:
throw new IllegalArgumentException("Bad type for: " + data.session);
}
convertView = mLayoutInflater.inflate(layoutId, parent, false);
}
switch(data.type){
case TYPE_GROUP:
TextView lblGroupDate = ((TextView)convertView.findViewById(R.id.lblGroupDate));
lblGroupDate.setText(DateUtils.formatDateTime(convertView.getContext(),
data.session.SESSION_DATE.getTime(), DateUtils.FORMAT_SHOW_DATE));
break;
case TYPE_SESSION:
TextView lblCourseCode = (TextView)convertView.findViewById(R.id.lblCourseCode);
lblCourseCode.setText(data.session.COURSE_CODE);
TextView lblSessionCode = (TextView)convertView.findViewById(R.id.lblSessionCode);
lblSessionCode.setText(data.session.SESSION_CODE);
break;
}
return convertView;
}
#Override
public Object getItem(int position)
{
return mData.get(position);
}
#Override
public long getItemId(int position)
{
return position;
}
#Override
public int getItemViewType(int position)
{
return mData.get(position).type;
}
#Override
public int getViewTypeCount()
{
return MAX_TYPES;
}
#Override
public int getCount()
{
return mData.size();
}
static class SessionViewData
{
int type;
SessionData session;
public SessionViewData(int type, SessionData session)
{
this.type = type;
this.session = session;
}
}
}
list_session_group.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/lblGroupDate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="#style/CustomText.GrayTitle"
/>
list_session_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layoutSessionItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:id="#+id/lblCourseCode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/CustomText.GrayText"
/>
<TextView
android:id="#+id/lblSessionCode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/CustomText.GrayText"
/>
</LinearLayout>

Android: How to set background of specific row in listView, without changing earlier entries

I am trying to make a chat program. My problem is that every time the background image updates(sender changes), every item in the array gets the same background. How can I change this so that outgoing messages get one type of background and incoming get another?
public class RowAdapter extends BaseAdapter {
private Context context;
private int textViewResourceId;
private final ArrayList<String> messageList;
private final ArrayList<String> senderList;
public String messageDirection;
boolean out;
public RowAdapter(Context context, int textViewResourceId, ArrayList<String> messageList, ArrayList<String> senderList) {
super();
this.textViewResourceId = textViewResourceId;
this.messageList = messageList;
this.senderList = senderList;
this.context = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
View rowView = convertView;
ViewHolder holder;
long timestamp = System.currentTimeMillis();
String readableTimestamp = (String)DateUtils.getRelativeTimeSpanString(timestamp);
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(textViewResourceId, parent, false);
holder = new ViewHolder();
holder.label = (TextView)rowView.findViewById(R.id.label);
holder.message=(TextView)rowView.findViewById(R.id.message);
holder.time = (TextView)rowView.findViewById(R.id.textTime);
holder.RL = (RelativeLayout)rowView.findViewById(R.id.userAndMessage);
rowView.setTag(holder);
}else{
holder = (ViewHolder)rowView.getTag();
}
holder.label.setText(senderList.get(position));
holder.message.setText(messageList.get(position));
holder.time.setText(readableTimestamp);
if(out){
if (messageList.get(position)!= null) {
holder.RL.setBackgroundResource(R.drawable.yellow);
((RelativeLayout) rowView).setGravity(Gravity.RIGHT);
}
}else{
if (messageList.get(position)!= null) {
holder.RL.setBackgroundResource(R.drawable.green);
((RelativeLayout) rowView).setGravity(Gravity.LEFT);
}
}
return rowView;
}
public void setOut(boolean out){
this.out = out;
}
static class ViewHolder{
RelativeLayout RL;
TextView label;
TextView message;
TextView time;
}
#Override
public int getCount() {
return messageList.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
}
Ok, try to do this
it's just an example and you have to add your process within it
Main layout xml
<LinearLayout 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: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=".MainActivity" >
<ListView
android:id="#+id/listView_Chat"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.1"
android:background="#123456"
android:gravity="center"
android:orientation="horizontal"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="fromMeBt"
android:text="From me" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="fromOtherBt"
android:text="From other" />
</LinearLayout>
</LinearLayout>
add a list row xml file
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
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" >
<TextView
android:id="#+id/txt_chat"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Create a new Class named ChatObject
public class ChatObject {
private String mssg;
private int from;
public ChatObject(String mssg, int from) {
super();
this.mssg = mssg;
this.from = from;
}
public String getMssg() {
return mssg;
}
public void setMssg(String mssg) {
this.mssg = mssg;
}
public int getFrom() {
return from;
}
public void setFrom(int from) {
this.from = from;
}
}
now, make some changes to your MainActivity like this
import java.util.ArrayList;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends Activity {
private ArrayList<ChatObject> items = new ArrayList<ChatObject>();
ListView listView_chat;
CustomAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
adapter = new CustomAdapter(items);
listView_chat = (ListView) findViewById(R.id.listView_Chat);
listView_chat.setAdapter(adapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void fromMeBt(View v) {
ChatObject object = new ChatObject("from me :)", 0);
items.add(object);
adapter.notifyDataSetChanged();
listView_chat.setSelection(items.size());
}
public void fromOtherBt(View v) {
ChatObject object = new ChatObject("from other :)", 1);
items.add(object);
adapter.notifyDataSetChanged();
listView_chat.setSelection(items.size());
}
class CustomAdapter extends BaseAdapter {
ArrayList<ChatObject> items;
public CustomAdapter(ArrayList<ChatObject> items) {
// TODO Auto-generated constructor stub
this.items = items;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return items.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return items.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_chat, null);
TextView txt_chat = (TextView) convertView.findViewById(R.id.txt_chat);
ChatObject object = items.get(position);
txt_chat.setText(object.getMssg());
if (object.getFrom() == 0) {
convertView.setBackgroundColor(Color.BLUE);
}else {
convertView.setBackgroundColor(Color.CYAN);
}
return convertView;
}
}
}
that's it, and if you want change the padding in xml layouts or add this to your dimens.xml file
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>
happy now? I hope this help you

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();
}
}

Categories

Resources