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);
Related
I have a ViewPager inside ListView in android screen:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/Base.TextAppearance.AppCompat.Menu"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentTop="true" />
</RelativeLayout>
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="55dip"
android:layout_alignParentEnd="false"
android:layout_alignParentStart="false"
android:layout_below="#+id/imageView"
android:autoText="false"
android:background="#FFFFFF"
android:gravity="center_vertical"
android:padding="10dp"
android:text="08/01 MidTown"
android:textColor="#21252D"
android:textSize="20sp" />
</RelativeLayout>
My ListFragment class
This class is calling the ArrayAdapter to load the data into above Textview.
public class FoodTabFragment extends ListFragment {
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getListView().setDivider(null);
final AppDelegate contextScope = (AppDelegate) getActivity().getApplicationContext();
FoodListAdapter adapt = new FoodListAdapter(getActivity().getApplicationContext(), R.layout.layout_listing_food, contextScope.foodList);
setListAdapter(adapt);
}
}
FoodListAdapter
public class FoodListAdapter extends ArrayAdapter<Food> {
private Context context;
private List<Food> foodList;
public FoodListAdapter(Context context, int resource, List<Food> objects) {
super(context, resource, objects);
this.context = context;
this.roomList = objects;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (null == convertView) {
convertView = inflater.inflate(R.layout.layout_listing_food, parent, false);
}
return convertView;
}
SlidingImageAdapter
public class SlidingImageAdapter extends PagerAdapter {
private ArrayList<Integer> IMAGES;
private LayoutInflater inflater;
private Context context;
public SlidingImageAdapter(Context context, ArrayList<Integer> IMAGES) {
this.context = context;
this.IMAGES=IMAGES;
inflater = LayoutInflater.from(context);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
#Override
public int getCount() {
return IMAGES.size();
}
#Override
public Object instantiateItem(ViewGroup view, int position) {
View imageLayout = inflater.inflate(R.layout.framelayout_listing_image_slider, view, false);
assert imageLayout != null;
final ImageView imageView = (ImageView) imageLayout
.findViewById(R.id.image);
imageView.setImageResource(IMAGES.get(position));
view.addView(imageLayout, 0);
return imageLayout;
}
Question
How can I merge slidingImageAdapter int FoodListAdapter. So that I can add viewpager in Listview in layout class?
In general I would suggest you to move to RecyclerView.
Below you can find simple solution for your current implementation.
Changes for FoodListAdapter:
Change list of food to map, where Food is id and related SlidingImageAdapter is value.
private Map<Food, SlidingImageAdapter> foodMap;
This will avoid recreating of adapter every getView call.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (null == convertView) {
convertView = inflater.inflate(R.layout.layout_listing_food, parent, false);
}
Food food = getItem(position);
SlidingImageAdapter adapter;
// adapter creation or reuse
if (foodMap.contains(food)) {
adapter = foodMap.get(food);
} else {
adapter = new SlidingImageAdapter(...);
foodMap.put(food, adapter);
}
convertView.findViewById(R.id.pager).setAdapter(adapter);
return convertView;
}
P.S. do not forget to override hashCode() and equals(Object o) in your Food entry.
Can someone point out what's the problem with this code snippet
Custom adapter
public class NavigationAdapter extends ArrayAdapter<NavItem> {
private Context context;
private NavItem[] values;
public NavigationAdapter(Context context, int layoutResourceId,NavItem[] values) {
super(context, layoutResourceId);
this.context = context;
this.values = values;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final Holder holder;
LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View convertView1 = convertView;
if (convertView1 == null) {
holder = new Holder();
convertView1 = vi.inflate(R.layout.item_row, parent,false);
holder.imageView = (ImageView) convertView1.findViewById(R.id.rowIcon);
holder.textView = (TextView) convertView1.findViewById(R.id.rowText);
convertView1.setTag(holder);
} else {
holder = (Holder) convertView1.getTag();
}
NavItem item = values[position];
holder.imageView.setImageResource(item.icon);
holder.textView.setText(item.name);
return convertView1;
}
private class Holder {
public TextView textView;
public ImageView imageView;
}
}
custom listview layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:background="?android:attr/activatedBackgroundIndicator"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:padding ="10dp">
<ImageView
android:id="#+id/rowIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:src="#drawable/ic_action_settings"
android:paddingRight="10dp"/>
<TextView
android:id="#+id/rowText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/rowIcon"
android:paddingRight="10dp"
android:textAppearance="?android:attr/textAppearanceListItemSmall"/>
Main activity
NavItem settings = new NavItem();
settings.icon = R.drawable.ic_action_settings;
settings.name = "Settings";
NavItem send = new NavItem(R.drawable.ic_action_settings,"Sent");
NavItem[] values = new NavItem[]{
settings,send
};
NavigationAdapter adapter = new NavigationAdapter(this, R.layout.item_row, values);
mDrawerListView.setAdapter(adapter);
When I open the drawer it just shows a blank page. If I change the adapter to ArrayAdapter of string and inflate the built in layout then it works, but I want to add image next to the text.
I have faced similar problem in my experience.
I solved this problem by changing :
public class NavigationAdapter extends ArrayAdapter<NavItem> {
}
to :
public class NavigationAdapter extends BaseAdapter<NavItem> {
}
I have extended my custom adapter from BaseAdapter class which have worked for my case. Please try this if it works for you also
In my app, I am creating a dynamic list of items using
shopsNameList = new ArrayList<String>();
// Create The Adapter
ArrayAdapter<String> arrayAdapter =
new ArrayAdapter<String>(ShopsListActivity.this, android.R.layout.simple_list_item_1, shopsNameList);
I would like to have a text and an image in each element of the list, not a simple text.
I defined a listviewitem.xml layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/listitemimage"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="#raw/shop" />
<TextView
android:id="#+id/textview"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Test" />
</LinearLayout>
and tried
ArrayAdapter<String> arrayAdapter =
new ArrayAdapter<String>(ShopsListActivity.this, R.layout.listviewitem, shopsNameList);
but my app crashes when I enter the list.
I am inside an activity creted with
super.onCreate(saveInstanceState);
setContentView(R.layout.shopslist);
// Get the reference of ListView
ListView shopsList=(ListView)findViewById(R.id.listShops);
shopsNameList = new ArrayList<String>();
shopElements = new ArrayList<ShopElement>();
You need to create custom adapter for your ListView:
public class CustomAdapter extends ArrayAdapter<String>{
Context context;
public CustomAdapter(Context context, List< String > objects)
{
super( context, R.layout.listviewitem, objects );
this.context = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ShopListHolder holder = null;
if(convertView == null)
{
LayoutInflater inflater = LayoutInflater.from( context );
convertView = inflater.inflate(R.layout.listviewitem, parent, false);
holder = new ShopListHolder();
holder.imgIcon = (ImageView)convertView.findViewById(R.id.listitemimage);
holder.txtTitle = (TextView)convertView.findViewById(R.id.textview);
convertView.setTag(holder);
}
else
{
holder = (ShopListHolder )convertView.getTag();
}
holder.txtTitle.setText(getItem( position ));
return convertView;
}
class ShopListHolder
{
ImageView imgIcon;
TextView txtTitle;
}
}
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) {
}
}