I followed several tutorials but I still can't populate my list view.
What am I doing wrong?
this is the layout spaced_list.xml
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mList"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
this is spaced_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:background="#efefef">
<TextView
android:id="#+id/leftItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:gravity="left"
android:text="Left Text View" />
<TextView
android:id="#+id/rightItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:gravity="right"
android:text="Right Text View" />
</RelativeLayout>
and this is the class
public class AllCategoriesActivity extends BaseActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.spaced_list);
ListView lv = (ListView) findViewById(R.id.mList);
TextView abHeader = (TextView) findViewById(R.id.header);
abHeader.setText("Categories");
CategoryDataSource cDataSource = new CategoryDataSource(this);
ArrayList<Category> allCategories = cDataSource.getAllCategories();
CategoriesAdapter cAdapter = new CategoriesAdapter(this, allCategories);
lv.setAdapter(cAdapter);
}
public class CategoriesAdapter extends ArrayAdapter<Category>{
private Context context;
private ArrayList<Category> categories;
public CategoriesAdapter(Context context, ArrayList<Category> categories){
super(context, 0);
this.context = context;
this.categories = categories;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.spaced_list_item, parent, false);
}
Category c = categories.get(position);
TextView tvLeft = (TextView) convertView.findViewById(R.id.leftItem);
tvLeft.setText(c.getTitle());
return convertView;
}
}
}
And I made sure that I'm getting values from cDataSource.getAllCategories();
Change this:
public CategoriesAdapter(Context context, ArrayList<Category> categories){
super(context, 0); // <- Wrong constructor
this.context = context;
this.categories = categories;
}
To this:
public CategoriesAdapter(Context context, ArrayList<Category> categories){
super(context, 0, categories);
this.context = context;
this.categories = categories;
}
You are currently calling this constructor of the super class:
public ArrayAdapter(Context context, int textViewResourceId) {
init(context, textViewResourceId, 0, new ArrayList<T>());
}
Which will eventually create a new ArrayList and ignore the data you passed in.
The problem is in the constructor in your adapter. You need to provide your ArrayList<Category> when you call super(). Here is the code:
public CategoriesAdapter(Context context, ArrayList<Category> categories){
super(context, 0, categories); //Providing objects to represent in the ListView
this.context = context;
this.categories = categories;
}
This is the documentation with the reference for this ArrayAdapter constructor.
Related
Hi StackOverflow community! I need your help understanding the following behavior:
I tried to implement a ListView for which each view follows the below layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearLWLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:weightSum="100">
<TextView
android:id="#+id/noteText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="66.6" />
<LinearLayout
android:id="#+id/linearVLWLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="33.3"
android:orientation="vertical">
<TextView
android:id="#+id/textcolor"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/reminder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textcolor" />
<TextView
android:id="#+id/location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/reminder" />
<TextView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/location" />
</LinearLayout>
Now, when I'm assigning elements to the list, I'm using the below adapter:
public class MyAdapter extends ArrayAdapter<Note> {
private Context mContext;
private int mResource;
public MyAdapter(#NonNull Context context, int resource, ArrayList<Note> objects) {
super(context, resource);
mContext =context;
mResource=resource;
}
public View getView(int position, View convertView, ViewGroup parent){
String text = getItem(position).getText();
String color = getItem(position).getColor();
String location = getItem(position).getLocation();
String reminder = getItem(position).getReminder();
String image = getItem(position).getImage();
Note note = new Note(text,color,location,reminder,image);
LayoutInflater inflater = LayoutInflater.from(mContext);
convertView=inflater.inflate(mResource,parent,false);
TextView nttxt = (TextView) convertView.findViewById(R.id.noteText);
TextView ntcolor = (TextView) convertView.findViewById(R.id.textcolor);
TextView ntrem = (TextView) convertView.findViewById(R.id.reminder);
TextView ntlocat = (TextView) convertView.findViewById(R.id.location);
TextView ntimg = (TextView) convertView.findViewById(R.id.image);
nttxt.setText(text);
ntcolor.setText(color);
ntrem.setText(reminder);
ntlocat.setText(location);
ntimg.setText(image);
Log.i("Convert",convertView.toString());
Log.i("Text",nttxt.toString());
return convertView;
}
}
The final result should be a list of notes together with user preferences and location/reminder.
Please see below the list assignation made on OnCreate method:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_explorer);
FloatingActionButton myFab = this.findViewById(R.id.fabAddNote);
myFab.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intentNoteEditor = new Intent(getApplicationContext(), NoteEditor.class);
startActivity(intentNoteEditor);
}
});
ListView notesList = (ListView) findViewById(R.id.listviewNotes);
Note note1 = new Note("Note1","Col1","Reminder1","Location1","Image1");
Note note2 = new Note("Note2","Col2","Reminder2","Location2","Image2");
Note note3 = new Note("Note3","Col3","Reminder3","Location3","Image3");
Note note4 = new Note("Note4","Col4","Reminder4","Location4","Image4");
ArrayList<Note> notesArray = new ArrayList<>();
notesArray.add(note1);
notesArray.add(note2);
notesArray.add(note3);
notesArray.add(note4);
Log.i("Notes",note1.getText().toString());
MyAdapter adapter = new MyAdapter(this,R.layout.list_item,notesArray);
notesList.setAdapter(adapter);
Log.i("Adapter",adapter.getContext().toString());
}
What am I doing wrong?
Any suggestions will be highly appreciated.
Thank you in advance!
You didn't store the list you feed your adapter to a local field.
Here you are passing ArrayList<Note> objects through the adapter constructor, but didn't save it locally to some store.
So, First modify your Adapter to have a filed of ArrayList<Note>
and initialize it in the constructor.
Second, override the adapter getCount() to return the size of your
list.
Third: modify your getView(), to get the Note object of the current
position in the list
public class MyAdapter extends ArrayAdapter<Note> {
private Context mContext;
private int mResource;
private ArrayList<Note> mNotes;
public MyAdapter(#NonNull Context context, int resource, ArrayList<Note> objects) {
super(context, resource);
mContext = context;
mResource = resource;
mNotes = objects;
}
#Override
public int getCount() {
return mNotes.size();
}
public View getView(int position, View convertView, ViewGroup parent){
String text = mNotes.get(position).getText();
String color = mNotes.get(position).getColor();
String location = mNotes.get(position).getLocation();
String reminder = mNotes.get(position).getReminder();
String image = mNotes.get(position).getImage();
// .... continue the rest of code.
Hope this address your issue.
I'm trying to customize ListView to show a list of images so i wrote the following code but unfortunately its not working.
layout/menu.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent" android:background="#drawable/menu_bg">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/name"
android:layout_gravity="center"/>
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/menu_list"
android:layout_gravity="center"
android:layout_marginTop="60sp"></ListView>
</LinearLayout>
layout/menu_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/item"/>
</LinearLayout>
Menu.java
public class Menu extends Activity{
private int[] items = {R.drawable.res_opt, R.drawable.new_game_opt, R.drawable.score_opt, R.drawable.exit_opt};
ListView list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.menu);
list = (ListView) findViewById(R.id.menu_list);
list.setAdapter(new MenuAdapter(Menu.this, items));
}
}
MenuAdapter.java
public class MenuAdapter extends ArrayAdapter{
private int[] items;
private Context context;
public MenuAdapter(Context context, int[] items) {
super(context, R.layout.menu_item);
this.context = context;
this.items = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//make sure we have a view to work with
View itemView = convertView;
if(itemView == null)
{
LayoutInflater inflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
itemView = inflater.inflate(R.layout.menu_item,null, true);
}
//Find the object to work with
int id = items[position];
//Fill the view
ImageView item = (ImageView) itemView.findViewById(R.id.item);
item.setImageResource(id);
return itemView;
}
}
Add view holder class to your code, as its incomplete.
public class ViewHolder{
public ImageView iv;
}
Now, your code will look like this:
ViewHolder mViewHolder = new ViewHolder();
if(itemView == null){
LayoutInflater inflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
itemView = inflater.inflate(R.layout.menu_item,null, null);
mViewHolder.iv = (ImageView) itemView.findViewById(R.id.item);
itemView.setTag(mViewHolder);
}else{
mViewHolder = (ViewHolder) itemView.getTag();
}
//Find the object to work with
int id = items[position];
//Fill the view
mViewHolder.iv.setImageResource(id);
Also, you have missed adding size for you ListView adapter.
Hope, this could help you.
You need to use another super constuctor of ArrayAdapter.
public class MenuAdapter extends ArrayAdapter<Integer>{
private Integer[] items;
private Context context;
public MenuAdapter(Context context, Integer[] items) {
super(context, R.layout.menu_item, items);
this.context = context;
this.items = items;
}
Edited
Also fix this line
itemView = inflater.inflate(R.layout.menu_item,parent, false);
I want to make a custom ListView with buttons as Items. Now I'm using the OnItemClickListener and for each click, a toast message comes up, but it only comes up, if i press out of the buttons, but in the ListView(see picture)
How can I do it, that the toast comes, if i press on the buttons, not out of them.
Adaptercode:
public class MainListAdapter extends ArrayAdapter<Games> {
Context context;
int layoutResourceId;
Games data[] = null;
public MainListAdapter(Context context, int layoutResourceId, Games[] 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;
ListHolder holder = null;
if(row == null){
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new ListHolder();
holder.btn = (Button)row.findViewById(R.id.listViewButton);
row.setTag(holder);
}else{
holder = (ListHolder)row.getTag();
}
Games games = data[position];
holder.btn.setText(games.name);
return row;
}
static class ListHolder {
Button btn;
}
}
In the Acitivty:
MainListAdapter adapter = new MainListAdapter(this, R.layout.listview_item_row, games_data);
listView1 = (ListView)findViewById(R.id.listView1);
final View header = (View)getLayoutInflater().inflate(R.layout.listview_newgame_row, null);
listView1.addHeaderView(header);
listView1.setAdapter(adapter);
listView1.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
Toast.makeText(getApplicationContext(), "clicked", Toast.LENGTH_LONG).show();
}
});
listview_item_row.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="#+id/listViewButton"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:focusable="false"
android:background="#drawable/button" />
IN your Adupter class make two objects for button.
And setonclicklistner for the buttons in adupter view
E.g.
vi = inflater.inflate(R.layout.list_row_contact, null);
LinearLayout ll_adpt_main = (LinearLayout)vi.findViewById(R.id.ll_adpt_main);
TextView name = (TextView) vi.findViewById(R.id.name);
TextView discription = (TextView) vi.findViewById(R.id.number);
ImageView iv = (ImageView)vi.findViewById(R.id.iv);
iv.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
}
});
return vi;
}
Make a separate onclicklistener for buttons. OnItemclicklistener is for a list item.
Firstly you have to create an xml layout like this.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="#+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
Then create an adapter class:
class MyAdapter extends ArrayAdapter<View.OnClickListener> {
public MyAdapter(Context context, int textViewResourceId, View.OnClickListener[] objects) {
super(context, textViewResourceId, objects);
}
public MyAdapter(Context context, int resource, int textViewResourceId, List<View.OnClickListener> objects) {
super(context, resource, textViewResourceId, objects);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.event_layout, null);
Button b = (Button) convertView.findViewById(R.id.btn);
View.OnClickListener l = getItem(position);
b.setOnClickListener(l);
return convertView;
}
}
The layout of the activity should be like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/LayoutActivity"
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=".YourActivityName" >
<Button
android:id="#+id/btnHeader1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<Button
android:id="#+id/btnHeader2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<ListView
android:id="#+id/your_list"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
</LinearLayout>
Now to set list items:
ListView list = (ListView)findViewById(R.id.your_list);
View.OnClickListener[] listeners = ....;
MyAdapter adapter = new MyAdapter(context, R.layout.your_list_layout_adapter, listeners);
list.setAdapter(adapter);
I hope to have satisfied all your requests :)
i'm having some trouble with my code app: i'm trying to display in an activity a list of image taken from an array but when i try to execute the app i've an empty list without error in debug. Can anyone help me? Here is my activity:
String [] vett;
ListView list;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_techpuno);
list=(ListView)findViewById(android.R.id.list);
Intent intent = getIntent();
vett=intent.getExtras().getStringArray("nomeImmagine");
for(int i = 0;i<vett.length;i++){
Log.d("test", vett[i]);}
//list.setListAdapter(new AdapterTecniche(this, vett));
list.setAdapter(new AdapterTecniche(this, R.layout.activity_techp,vett));
}
And here it is the adapter:
public class AdapterTecniche extends ArrayAdapter<String> {
private final int resource;
private final String[] img;
public ImageLoader imageLoader;
LayoutInflater inflater;
public AdapterTecniche(Context context,int resource, String[]img) {
// your code
super(context, R.layout.activity_techpuno);
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.context = context;
this.resource=resource;
this.img=img;
imageLoader=new ImageLoader(getContext().getApplicationContext());
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
View rowView = convertView;
if(rowView == null) {
Log.d("errore","Immagini non presenti");
rowView = inflater.inflate(R.layout.immagini, parent, false);
viewHolder=new ViewHolder();
viewHolder.imageView=(ImageView) rowView.findViewById(R.id.list_image);
rowView.setTag(viewHolder);
}
else
{
viewHolder=(ViewHolder)rowView.getTag();
}
if(img==null){
Log.d("errore","Immagini non presenti");
}else{
int resourceId = context.getResources().getIdentifier(img[position],"drawable", context.getPackageName());
for(int i=0;i<img.length;i++){
Log.d("err", img[i]);
}
imageLoader.DisplayImage(resourceId, viewHolder.imageView);
}
return rowView;
}
static class ViewHolder {
ImageView imageView;
}
}
Immagini.xml (each image layout)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/list_image"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:layout_gravity="center_horizontal" />
</LinearLayout>
And Activity layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#android:id/list" />
</LinearLayout>
setContentView(R.layout.activity_techpuno);
should be before
list=(ListView)findViewById(R.id.listView);
Because Activity firstly need to have binded/inflated layout, after that you can "find" your views from it.
Edit
Use ArrayAdapter(Context context, int resource, T[] objects) constructor to give objects to it.
Or override getCount() because your adapter have no idea how many items he got.
I'm looking for a clear way to establish the XML resource for a list of strings with an image attached to it.
Should I use attributes? What is the best practice?
list_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ListView android:id="#+id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
row_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="#+id/row_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView android:id="#+id/row_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
In onCreate()
setContentView(R.layout.list_layout);
ListView lv = (ListView) findViewById(R.id.list);
List<ListRow> list = new ArrayList<ListRow>();
for ( loop through your data ) {
list.add(new ListRow("text", R.drawable.image));
}
YourAdapter adapter = new YourAdapter(this, list);
lv.setAdapter(adapter);
The classes
class ListRow {
private String text;
private int resource;
public ListRow(String text, int resource) {
super();
this.text = text;
this.resource = resource;
}
public int getText() {
return text;
}
public int getResource() {
return resource;
}
}
class YourAdapter extends BaseAdapter implements OnClickListener {
private Context context;
private List<ListRow> theList;
public YourAdapter (Context context, List<ListRow> theList) {
this.context = context;
this.theList = theList;
}
public View getView(int position, View convertView, ViewGroup viewGroup) {
ListRow row = theList.get(position);
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.row_layout, null);
}
TextView tv = (TextView) convertView.findViewById(R.id.row_text);
tv.setText(row.getText());
ImageView iv = (ImageView) convertView.findViewById(R.id.row_image);
iv.setBackgroundResource(row.getResource());
return convertView;
}
#Override
public void onClick(DialogInterface dialog, int which) {
}
}