I am working on a college project to build an android based mobile learning app. I'm using Parse for backend services. There is a class, namely 'Course' which contains name of the courses to be offered along with an icon for each course. I have written code for custom adapter to display a list of all the courses with icons. The project is executing but the list is not appearing. I cannot figure out what is going wrong.
Here is my SelectCourse.java code
final List<Item> items=new ArrayList<Item>();
ParseQuery<ParseObject> query = ParseQuery.getQuery("Course");
query.orderByAscending("name");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> list, ParseException e) {
if (e == null) {
if (list.size() > 0)
for (int i = 0; i < list.size(); i++) {
final String course = list.get(i).getString("name");
ParseFile image = list.get(i).getParseFile("image");
//adapter.add(course.getString("name"));
image.getDataInBackground(new GetDataCallback() {
public void done(byte[] data, ParseException e) {
if (e == null) {
Bitmap icon = BitmapFactory.decodeByteArray(
data, 0, data.length);
Item item = new Item(icon, course);
items.add(item);
} else {
Toast.makeText(getApplicationContext(),
e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
});
}
} else {
Toast.makeText(getApplicationContext(),
e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
});
CustomAdapter adapter=new CustomAdapter(this,items);
ListView listView = (ListView) findViewById(R.id.course_list);
listView.setAdapter(adapter);
This is my CustomAdapter.java code
public class CustomAdapter extends BaseAdapter {
private Context context;
private List<Item> list;
CustomAdapter(Context context, List<Item> list){
this.context = context;
this.list = list;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int position) {
return list.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView=convertView;
if(rowView==null) {
ViewHolder viewHolder = new ViewHolder();
LayoutInflater layoutInflater = (LayoutInflater) context.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = layoutInflater.inflate(R.layout.list_select_course, parent, false);
viewHolder.icon = (ImageView) rowView.findViewById(R.id.rowImageView);
viewHolder.text = (TextView) rowView.findViewById(R.id.rowTextView);
rowView.setTag(viewHolder);
}
ViewHolder viewHolder = (ViewHolder) rowView.getTag();
viewHolder.icon.setImageBitmap(list.get(position).image);
viewHolder.text.setText(list.get(position).text);
return rowView;
}}
Here are ViewHolder and Item
public class ViewHolder {
ImageView icon;
TextView text;}
public class Item {
Bitmap image;
String text;
Item(Bitmap image, String text){
this.image=image;
this.text=text;
}}
This is content_select_course.xml
<LinearLayout 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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.rsa.minerva.SelectCourseActivity"
tools:showIn="#layout/app_bar_select_course">
<ListView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/course_list"
android:layout_weight="1" />
And finally list_select_course.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:padding="16dp">
<ImageView
android:id="#+id/rowImageView"
android:layout_width="48dp"
android:layout_height="48dp" />
<TextView
android:id="#+id/rowTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/colorButton"
android:text="Hello World"/>
This part of the code:
query.findInBackground(new FindCallback<ParseObject>()
Doesn't run synchronously, meaning that you are actually creating an adapter with no data:
Put this snippet before you call the query.findInBackground():
CustomAdapter adapter=new CustomAdapter(this,items);
ListView listView = (ListView) findViewById(R.id.course_list);
listView.setAdapter(adapter);
And then inside the public void done() callback, put:
adapter.notifyDataSetChanged();
After you add the items to the list with items.add(item).
That should do it.
Related
I am trying to implement a search function for android's grid view. However, every time i search a image , i do not get the correct image with its text. Below is my code. Any help is greatly appreciated :) My filter logic seems to be correct based on the log statements that i printed out. However the image and text is not filtered correctly.
MainActivity.
public class MainActivity extends AppCompatActivity {
final String TAG = "MainActivity";
GridView searchGrid;
ImageAdapter adapter;
int[] resourceIds = new int[]{R.drawable.sample_0, R.drawable.sample_1, R.drawable.sample_2,
R.drawable.sample_3, R.drawable.sample_4, R.drawable.sample_5};
String[] names = new String[]{"sample 0", "sample 1", "sample 2", "sample 3", "sample 4",
"testImage"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
searchGrid = findViewById(R.id.searchGrid);
adapter = new ImageAdapter(this, this.getModels());
searchGrid.setAdapter(adapter);
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.search_menu, menu);
MenuItem item = menu.findItem(R.id.search_food);
SearchView searchView = (SearchView) item.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String s) {
return false;
}
#Override
public boolean onQueryTextChange(String s) {
adapter.filter(s);
return false;
}
});
return super.onCreateOptionsMenu(menu);
}
private List<DataModel> getModels() {
List<DataModel> models = new ArrayList<>();
DataModel dm;
for (int i = 0; i < names.length; i++) {
dm = new DataModel(resourceIds[i], names[i]);
models.add(dm);
}
return models;
}
class ImageAdapter extends BaseAdapter {
private Context mContext;
private List<DataModel> dataModels;
private List<DataModel> filterList = new ArrayList<>();
public ImageAdapter(Context context, List<DataModel> dataModels) {
mContext = context;
this.dataModels = dataModels;
this.filterList.addAll(dataModels);
}
#Override
public int getCount() {
return dataModels.size();
}
#Override
public Object getItem(int i) {
return dataModels.get(i);
}
#Override
public long getItemId(int i) {
return dataModels.indexOf(getItem(i));
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ImageView imageView;
if (view == null) {
// if it's not recycled, initialize some attributes
view = layoutInflater.inflate(R.layout.single_item, null);
imageView = view.findViewById(R.id.imageView);
TextView textView = view.findViewById(R.id.textView);
imageView.setImageResource(dataModels.get(i).resourceId);
textView.setText(dataModels.get(i).imageName);
}
return view;
}
public void filter(CharSequence text) {
String query = text.toString().toLowerCase();
//Log.i(TAG,query);
dataModels.clear();
if (text.length() == 0 ) {
dataModels.addAll(filterList);
} else {
for (DataModel dm : filterList) {
if (dm.imageName.toLowerCase().contains(query)) {
Log.i(TAG,dm.imageName + " " + query);
dataModels.add(dm);
}
}
}
notifyDataSetChanged();
}
}
MainActivity xml file.
<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"
tools:context=".MainActivity">
<GridView
android:padding="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/searchGrid"
android:numColumns="auto_fit"
android:columnWidth="120dp"
android:gravity="center">
</GridView>
</RelativeLayout>
single_item xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="#+id/imageView" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/textView"
android:layout_below="#+id/imageView"
android:layout_alignStart="#+id/imageView"
android:layout_alignEnd="#+id/imageView"
/>
search_manu xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/search_food"
android:title="Search Myfoods"
android:icon="#android:drawable/ic_menu_search"
app:actionViewClass="android.widget.SearchView"
app:showAsAction="always">
</item>
Try to change your code like this. Maybe it helps.
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ImageView imageView;
if (view == null) {
// if it's not recycled, initialize some attributes
view = layoutInflater.inflate(R.layout.single_item, null);
}
imageView = view.findViewById(R.id.imageView);
TextView textView = view.findViewById(R.id.textView);
imageView.setImageResource(dataModels.get(i).resourceId);
textView.setText(dataModels.get(i).imageName);
return view;
}
Your filter code is alright but you are not displaying the items properly. Even when your view is already initialized you need to fill correct data in the views else the view will show previous items data. Modify your code like this
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (view == null) {
view = layoutInflater.inflate(R.layout.single_item, null);
}
ImageView imageView = view.findViewById(R.id.imageView);
TextView textView = view.findViewById(R.id.textView);
imageView.setImageResource(dataModels.get(i).resourceId);
textView.setText(dataModels.get(i).imageName);
return view;
}
Also try using holder pattern so that you don't have to find view by its id everytime. It will save some run time on UI thread
I'd like to create a ListView and add items dynamically. Here is my code:
CustomAdapter.java:
public class CustomAdapter extends ArrayAdapter<Item>{
Context context;
int layoutResourceId;
LinearLayout linearMain;
ArrayList<Item> data = new ArrayList<Item>();
public CustomAdapter(Context context, int layoutResourceId,
ArrayList<Item> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
linearMain = (LinearLayout) row.findViewById(R.id.lineraMain);
Item myImage = data.get(position);
TextView label = new TextView(context);
label.setText(myImage.name);
linearMain.addView(label);
ImageView image = new ImageView(context);
int outImage = myImage.image;
image.setImageResource(outImage);
linearMain.addView(image);
}
return row;
}
}
Item.java:
public class Item {
int image;
String name;
public Item(int image, String name) {
super();
this.image = image;
this.name = name;
}
public int getImage() {
return image;
}
public void setImage(int image) {
this.image = image;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
GallerF.java
ArrayList<Item> imageArry = new ArrayList<Item>();
CustomAdapter adapter;
ListView dataList;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_gallery, parent, false);
dataList = (ListView) v.findViewById(R.id.lista);
return v;
}
.....
public void CreateNewListRow(){
imageArry.add(new Item(R.drawable.ek_logo,name));
adapter = new CustomAdapter(getActivity(),R.layout.list,imageArry);
dataList.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
list.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/lineraMain"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:padding="10dp" >
</LinearLayout>
activity_gallery.xml
<?xml version="1.0" encoding="utf-8"?>
<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: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="hu.redbuttonebb.endi.fragmentek20.GalleryF"
android:background="#drawable/background"
android:id="#+id/linlayout">
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ListView
android:id="#+id/lista"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:drawSelectorOnTop="false" />
</ScrollView>
</LinearLayout>
Now when I run the app it's create one row with the correct picture and name. But when I'd like to create one more then nothing happen. Where do I do it wrong?
Replace your file with this:
ArrayList<Item> imageArry = new ArrayList<Item>();
CustomAdapter adapter;
ListView dataList;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_gallery, parent, false);
dataList = (ListView) v.findViewById(R.id.lista);
adapter = new CustomAdapter(getActivity(),R.layout.list,imageArry);
dataList.setAdapter(adapter);
return v;
}
.....
public void CreateNewListRow(){
imageArry.add(new Item(R.drawable.ek_logo,name));
imageArry.add(new Item(R.drawable.ek_logo,name));
imageArry.add(new Item(R.drawable.ek_logo,name));
imageArry.add(new Item(R.drawable.ek_logo,name));
imageArry.add(new Item(R.drawable.ek_logo,name));
adapter.notifyDataSetChanged();
}
Edit your list.xml with below code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/lineraMain"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp" >
</LinearLayout>
Remove ScrollView, ListView do not require ScrollView:
<?xml version="1.0" encoding="utf-8"?>
<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: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="hu.redbuttonebb.endi.fragmentek20.GalleryF"
android:background="#drawable/background"
android:id="#+id/linlayout">
<ListView
android:id="#+id/lista"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:drawSelectorOnTop="false" />
</LinearLayout>
Add this method to Adapter & extends Adapter to BaseAdapter
public class FriendsAdapter extends BaseAdapter {
Activity context;
ArrayList<String> data = new ArrayList<>();
LayoutInflater inflater;
public FriendsAdapter(Activity c) {
context = c;
inflater = LayoutInflater.from(this.context);
}
public void add(String item) {
try {
data.add(item);
} catch (Exception e) {
e.printStackTrace();
}
notifyDataSetChanged();
}
public void remove(int position) {
try {
data.remove(data.get(position));
} catch (Exception e) {
e.printStackTrace();
}
notifyDataSetChanged();
}
#Override
public int getCount() {
return data.size();
}
#Override
public String getItem(int position) {
return data.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_item_friends, parent, false);
holder = new ViewHolder();
holder.tvUserName = (TextView) convertView.findViewById(R.id.tvUserName);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
try {
holder.tvUserName.setText(data.get(position));
} catch (Exception e) {
e.printStackTrace();
}
return convertView;
}
private class ViewHolder {
TextView tvUserName;
}}
Initializing Adapter
FriendsAdaoter adapter = new FriendsAdapter(this);
list.setAdapter(adapter);
adapter.add("ABCDEFGHIJKL");
You are creating a new Adapter every time you want to add an item. You need to create a method in your adapter and call that method when you add an item, like this:
public class CustomAdapter extends ArrayAdapter<Item>{
Context context;
int layoutResourceId;
LinearLayout linearMain;
ArrayList<Item> data = new ArrayList<Item>();
public CustomAdapter(Context context, int layoutResourceId,
ArrayList<Item> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
linearMain = (LinearLayout) row.findViewById(R.id.lineraMain);
Item myImage = data.get(position);
TextView label = new TextView(context);
label.setText(myImage.name);
linearMain.addView(label);
ImageView image = new ImageView(context);
int outImage = myImage.image;
image.setImageResource(outImage);
linearMain.addView(image);
}
return row;
}
public void addItem(Item item) {
data.add(item);
notifyDataSetChanged();
}
and change your CreateNewListRow to this:
public void CreateNewListRow(){
adapter.addItem(new Item(R.drawable.ek_logo,name));
}
and change your onCreate to this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_gallery, parent, false);
dataList = (ListView) v.findViewById(R.id.lista);
adapter = new CustomAdapter(getActivity(),R.layout.list,imageArry);
dataList.setAdapter(adapter);
return v;
}
I'm trying to populate a listview with the id android.id/list with some xml data.. The data is successfully requested and I get no errors when passing it to my Lazy Adapter and setting it to the listview.. Can somebody help me?
The request:
private void requestFeed() {
SimpleXmlRequest<StationList> simpleRequest = new SimpleXmlRequest<StationList>(Request.Method.GET, url, StationList.class,
new Response.Listener<StationList>()
{
#Override
public void onResponse(StationList response) {
list = response.getStationList();
buildFeed();
if(mSplashDialog != null) {
removeSplashScreen();
} else {
setReloadFeedButtonState(false);
}
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
// error Object
Log.d("TESTE", error.toString());
}
}
);
simpleRequest.setTag(SIMPLE_TAG);
queue = Volley.newRequestQueue(this);
queue.add(simpleRequest);
}
The buildFeed:
private void buildFeed() {
if(stations == null) {
stations = (ListView) findViewById(android.R.id.list);
adapter = new LazyAdapter(this, list);
stations.setAdapter(adapter);
}
adapter.notifyDataSetChanged();
}
The adapter:
public class LazyAdapter extends BaseAdapter {
private List<Station> stations;
private static LayoutInflater inflater = null;
public LazyAdapter(Activity activity, List<Station> stations) {
this.stations = stations;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return stations.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
if(convertView == null)
vi = inflater.inflate(R.layout.list_row, null);
TextView name = (TextView) vi.findViewById(R.id.station_name);
TextView ct = (TextView) vi.findViewById(R.id.station_ct);
TextView cl = (TextView) vi.findViewById(R.id.station_cl);
Station tmp = stations.get(position);
name.setText(tmp.get_name());
ct.setText(tmp.get_ct());
cl.setText(tmp.get_lc().toString());
return vi;
}
}
the xml of the activity
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:id="#+id/MainActivityLL"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="me...MainActivity" >
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:divider="#color/list_divider"
android:dividerHeight="1dp"
android:layout_weight="1"
android:listSelector="#drawable/list_row_selector" />
<TextView
android:id="#android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textAppearance="#android:style/TextAppearance.Medium"
android:text="#string/emptyList"
android:gravity="center" />
I've checked the stations list that comes in the response and is not empty.. I have all the data I need, but the listview is always showing the empty message from the textview with id android.id/empty ..
Remove android:id="#android:id/list"
Replace it with android:id="#+id/list"
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:divider="#color/list_divider"
android:dividerHeight="1dp"
android:layout_weight="1"
android:listSelector="#drawable/list_row_selector" />
Try to Use ViewHolder design pattern when you make custom adapter :
public class LazyAdapter extends BaseAdapter {
private List<Station> stations;
private Context context;
public LazyAdapter(Context context, List<Station> stations) {
this.stations = stations;
this.context=context;
}
public int getCount() {
return stations.size();
}
public Object getItem(int position) {
return stations.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null){
holder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.list_row, null);
holder.name = (TextView) convertView.findViewById(R.id.station_name);
holder.ct = (TextView) convertView.findViewById(R.id.station_ct);
holder.cl = (TextView) convertView.findViewById(R.id.station_cl);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
holder.name.setText(stations.get(position).get_name());
holder.ct.setText(stations.get(position).get_ct());
holder.cl.setText(stations.get(position).get_lc().toString());
return convertView;
}
class ViewHolder{
TextView name;
TextView ct;
TextView cl;
}
}
I'm learning Android SDK and I need some advices.
I have custom ListView with BaseAdapter and I want to implement some new feature - Favorite Button.
What I want to do is, when I press the Favorite Button, ListItem goes to the beginning of the list, Favorite image change and all that stuff will be saved in the SharedPrefs.
Someone tell me what I need to do, to make it works?
my existing code:
row.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/layout_element_list"
>
<ImageView
android:id="#+id/icon"
android:layout_width="150dp"
android:padding="5dp"
android:layout_height="150dp"
android:layout_marginLeft="4px"
android:layout_marginRight="10px"
android:layout_marginTop="4px"
android:src="#drawable/radio" >
</ImageView>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="#+id/label"
android:paddingTop="20dp"
android:layout_gravity="center_vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:textAlignment="center"
android:text="RadioName"
android:textColor="#color/color1"
android:textSize="30dp" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
<TextView
android:id="#+id/label2"
android:layout_gravity="center_vertical"
android:layout_width="fill_parent"
android:layout_weight="1"
android:layout_height="fill_parent"
android:textAlignment="center"
android:text="Description.."
android:textColor="#color/color1"
android:textSize="15dp" />
<ImageView
android:id="#+id/favButton"
android:layout_weight="1"
android:layout_width="fill_parent"
android:padding="5dp"
android:layout_height="fill_parent"
android:layout_marginLeft="4px"
android:layout_marginRight="10px"
android:layout_marginTop="4px"
android:src="#drawable/fav_off" >
</ImageView>
</LinearLayout>
</LinearLayout>
</LinearLayout>
BaseAdapter class:
public class RadioAdapter extends BaseAdapter
{
ArrayList<RadioStation> myList = new ArrayList<RadioStation>();
LayoutInflater inflater;
Context context;
public RadioAdapter(Context context, ArrayList<RadioStation> myList) {
this.myList = myList;
this.context = context;
inflater = LayoutInflater.from(this.context);
}
#Override
public int getCount() {
return myList.size();
}
#Override
public RadioStation getItem(int position) {
return myList.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
MyViewHolder mViewHolder;
if(convertView == null) {
convertView = inflater.inflate(R.layout.activity_menu_row, null);
mViewHolder = new MyViewHolder();
convertView.setTag(mViewHolder);
} else {
mViewHolder = (MyViewHolder) convertView.getTag();
}
mViewHolder.tvTitle = detail(convertView, R.id.label, myList.get(position).getTitle());
mViewHolder.tvDesc = detail(convertView, R.id.label2, myList.get(position).getDescription());
mViewHolder.ivIcon = detail(convertView, R.id.icon, myList.get(position).getImgResId());
return convertView;
}
private TextView detail(View v, int resId, String text) {
TextView tv = (TextView) v.findViewById(resId);
tv.setText(text);
return tv;
}
private ImageView detail(View v, int resId, int icon) {
ImageView iv = (ImageView) v.findViewById(resId);
iv.setImageResource(icon); //
return iv;
}
private class MyViewHolder {
TextView tvTitle, tvDesc;
ImageView ivIcon;
}
}
RadioStation class:
public class RadioStation
{
public String title;
public String description;
public int imgResId;
//getters and setters
public static Comparator<RadioStation> comparatorByRadioName = new Comparator<RadioStation>()
{
#Override
public int compare(RadioStation radioStation, RadioStation radioStation2)
{
String name1 = radioStation.getTitle().toLowerCase();
String name2 = radioStation2.getTitle().toLowerCase();
return name1.compareTo(name2);
}
};
}
ActivityListView:
public class ActivityMenuList extends Activity implements AdapterView.OnItemClickListener
{
private ListView lvDetail;
private Context context = ActivityMenuList.this;
private ArrayList <RadioStation> myList = new ArrayList <RadioStation>();
private String[] names = new String[] { "one", "two", "three" };
private String[] descriptions = new String[] { "notset", "notset", "notset"};
private int[] images = new int[] { R.drawable.one, R.drawable.two, R.drawable.three };
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
getWindow().setBackgroundDrawableResource(R.drawable.bg1);
setContentView(R.layout.activity_menu_list);
lvDetail = (ListView) findViewById(R.id.list);
lvDetail.setOnItemClickListener(this);
getDataInList();
lvDetail.setAdapter(new RadioAdapter(context, myList));
}
private void getDataInList() {
for(int i=0;i<3;i++) {
RadioStation ld = new RadioStation();
ld.setTitle(names[i]);
ld.setDescription(descriptions[i]);
ld.setImgResId(images[i]);
myList.add(ld);
}
Collections.sort(myList, RadioStation.comparatorByRadioName);
}
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l)
{
String item = names[i];
Intent e = new Intent(ActivityMenuList.this, ActivityRadioStation.class);
Bundle data = new Bundle();
data.putString("radiostation",item);
e.putExtras(data);
startActivity(e);
}
}
That's a lot of changes you have to do. Let's start with the basic.
Add a boolean to your RadioStation for the favorite state.
public boolean isFavorite;
Next on your getView add the favorite button click listener(add its reference to the viewholder too, but let's keep it simple this time)
public class RadioAdapter extends BaseAdapter
{
ArrayList<RadioStation> myList = new ArrayList<RadioStation>();
LayoutInflater inflater;
Context context;
ListView mListview;
public RadioAdapter(Context context, ArrayList<RadioStation> myList, ListView list) {
this.myList = myList;
this.context = context;
mListView = list;
inflater = LayoutInflater.from(this.context);
}
#Override
public int getCount() {
return myList.size();
}
#Override
public RadioStation getItem(int position) {
return myList.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
MyViewHolder mViewHolder;
if(convertView == null) {
convertView = inflater.inflate(R.layout.activity_menu_row, null);
mViewHolder = new MyViewHolder();
convertView.setTag(mViewHolder);
} else {
mViewHolder = (MyViewHolder) convertView.getTag();
}
mViewHolder.tvTitle = detail(convertView, R.id.label, myList.get(position).getTitle());
mViewHolder.tvDesc = detail(convertView, R.id.label2, myList.get(position).getDescription());
mViewHolder.ivIcon = detail(convertView, R.id.icon, myList.get(position).getImgResId());
convertView.findViewById(R.id.favButton).setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
myList.get(position).isFavorite=! myList.get(position).isFavorite;
//reorder mlist
notifyDataSetChanged();
//mListView. smoothscroll here
}
});
((ImageView) convertView.findViewById(R.id.favButton)).setImageResource(myList.get(position).isFavorite?R.drawable.favoriteOn:R.drawable.favoriteOff);
return convertView;
}
private TextView detail(View v, int resId, String text) {
TextView tv = (TextView) v.findViewById(resId);
tv.setText(text);
return tv;
}
private ImageView detail(View v, int resId, int icon) {
ImageView iv = (ImageView) v.findViewById(resId);
iv.setImageResource(icon); //
return iv;
}
private class MyViewHolder {
TextView tvTitle, tvDesc;
ImageView ivIcon;
}
}
I left commented what you should do on the listener. You should be able to continue from here.
When you create your adapter pass the list as the last parameter on the constructor.
Edited: Removed interface. No need to use it here.
i need create a custom adapter for a listview but i can't understand how could do it. Actually it works my work but using simply a listview with all objects inside the default android layout for the lists. I need "separate" the objects creating the custom adapter. This is the actual code:
private static class SoluzioniLoader extends AsyncTaskLoader<List<Soluzione>> {
private FermataComune partenza;
private FermataComune arrivo;
private String data;
public SoluzioniLoader(Context context, FermataComune partenza, FermataComune arrivo, String data) {
super(context);
this.partenza = partenza;
this.arrivo = arrivo;
this.data = data;
}
#Override
public List<Soluzione> loadInBackground() {
try {
List<Soluzione> soluzioni = Client.cercaCorseAndata(partenza, arrivo, data);
return soluzioni;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
private LoaderCallbacks<List<Soluzione>> mLoaderCallbacks = new LoaderCallbacks<List<Soluzione>>() {
private ProgressDialog pd;
#Override
public Loader<List<Soluzione>> onCreateLoader(int id, Bundle args) {
pd = new ProgressDialog(SoluzioniActivity.this);
pd.setTitle("Caricamento Soluzioni Trovate");
pd.setMessage("Attendi...");
pd.setIndeterminate(false);
pd.show();
return new SoluzioniLoader(SoluzioniActivity.this, partenza, arrivo, data);
}
#Override
public void onLoadFinished(Loader<List<Soluzione>> loader, List<Soluzione> data) {
try {
pd.dismiss();
} catch(Exception e){
}
if (data == null) {
// ERRORE
} else {
mListView.setAdapter(new ArrayAdapter<Soluzione>(SoluzioniActivity.this, android.r.layout.simple_list_item_1, data));
}
I've already created a layout for the row
<?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"
>
<TextView
android:id="#+id/fromhour"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
/>
<TextView
android:id="#+id/from"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
/>
<TextView
android:id="#+id/tohour"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
/>
<TextView
android:id="#+id/to"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
/>
</LinearLayout>
Any help how could i create and integrate a custom adapter here? Thanks
Try below code:
//Declare your custom adapter:
private EfficientAdapter adapter;
In onCreate() initialize it:
adapter = new EfficientAdapter(this);
Then set your list adapter,
your_listview.setAdapter(adapter);
//Your adapter code:
private class EfficientAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private Context context;
private Bitmap imageBitmap = null;
public EfficientAdapter(Context context) {
mInflater = LayoutInflater.from(context);
this.context = context;
}
#Override
public int getCount() {
return YOUR_ARRAY.size();
}
#Override
public Object getItem(int arg0) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.featured_item, null);
holder = new ViewHolder();
holder.txtTitle = (TextView) convertView.findViewById(R.id.txtTitle);
holder.txtAuthorName = (TextView) convertView.findViewById(R.id.txtAuthorName);
holder.txtDescription = (TextView) convertView.findViewById(R.id.txtDescription);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.txtTitle.setText(data.get(position).get("article_title"));
holder.txtAuthorName.setText(data.get(position).get("author_name"));
holder.txtDescription.setText(data.get(position).get("article_text"));
return convertView;
}
class ViewHolder {
//YOUR ATTRUBUTES TO DISPLAY IN LIST DECLARE HERE
TextView txtTitle;
TextView txtAuthorName;
TextView txtDescription;
}
}