How to create Spinner-list using CustomAdapter in android
Asked Answered
N

3

31

in my app,I want to create SpinnerList using CustomAdapter class,For this i wrote below code but when I tap on spinner list then array-List images are not loading in spinner-list as like my below screen why this problem is coming?

main_layout.xml:-

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dip"
        android:text="Category:"
        android:layout_marginBottom="5dp"/>

    <Spinner
        android:id="@+id/spinner"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

MainActivity:-

public class MainActivity extends AppCompatActivity  {

    public static final String[] titles = new String[] { "Strawberry",
            "Banana", "Orange", "Hello" };

    public static final Integer[] images = { R.drawable.image1,
            R.drawable.image2, R.drawable.image3, R.drawable.image4 };

    Spinner spinner;
    List<RowItem> rowItems;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_layout);

        rowItems = new ArrayList<RowItem>();
        for (int i = 0; i < titles.length; i++) {

            RowItem item = new RowItem(titles[i],images[i]);
            rowItems.add(item);
        }

        spinner = (Spinner)findViewById(R.id.spinner);
       CustomAdapter adapter = new CustomAdapter(MainActivity.this,
            R.layout.listitems_layout, R.id.title, rowItems);
        spinner.setAdapter(adapter);
    }
}

listitems_layout.xml:-

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <ImageView
        android:id="@+id/icon"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:src="@drawable/image1"
        android:padding="10dp"
        />

    <TextView
        android:layout_marginTop="30dp"
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/icon"
        android:textColor="#CC0033"
        android:text="Strawberry"
        android:textSize="16dp" />

</LinearLayout>

CustomAdapter:-

package com.example.venkat.spinnerexample1;


import android.app.Activity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.view.LayoutInflater;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

public class CustomAdapter extends ArrayAdapter<RowItem> {

    LayoutInflater flater;

     public CustomAdapter(Activity context,int resouceId, int textviewId, List<RowItem> list){

    super(context,resouceId,textviewId, list);
    flater = context.getLayoutInflater();
}

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        RowItem rowItem = getItem(position);

        View rowview = flater.inflate(R.layout.listitems_layout,null,true);

        TextView txtTitle = (TextView) rowview.findViewById(R.id.title);
        txtTitle.setText(rowItem.getTitle());

        ImageView imageView = (ImageView) rowview.findViewById(R.id.icon);
        imageView.setImageResource(rowItem.getImageId());

        return rowview;
    }
}

RowItem:-

package com.example.venkat.spinnerexample1;

public class RowItem {

    private int ImageId;
    private String Title;

    public RowItem(String Title,int ImageId){

        this.Title = Title;
        this.ImageId = ImageId;
    }

    public String getTitle(){

        return Title;
    }

    public void setTitle(String Title){

        this.Title = Title;
    }

    public int getImageId(){

        return ImageId;
    }

    public void setImageId(int ImageId){

        this.ImageId = ImageId;
    }

    @Override
    public String toString() {
        return Title ;
    }
}

screen:- ---enter image description here

Northcliffe answered 14/3, 2016 at 8:59 Comment(2)
what is the exception?Fulbright
java.lang.IllegalStateException: ArrayAdapter requires the resource ID to be a TextView this is exceptionNorthcliffe
F
30

Inside your adapter constructor, send the id of textview also

public CustomAdapter(Activity context,int resouceId, int textviewId, List<RowItem> list){

        super(context,resouceId,textviewId, list);
        flater = context.getLayoutInflater();
    }

call it by

CustomAdapter adapter = new CustomAdapter(MainActivity.this,
                R.layout.listitems_layout, R.id.title, rowItems);

EDIT Your images are not showing because you didn't override the getDropdownView() method. This method decides the layout of child when dropdown is visible. So add this method to your adapter

@Override
        public View getDropDownView(int position, View convertView, ViewGroup parent) {
            if(convertView == null){
                convertView = flater.inflate(R.layout.list_itemslayout,parent, false);
            }
            RowItem rowItem = getItem(position);
            TextView txtTitle = (TextView) convertView.findViewById(R.id.title);
            txtTitle.setText(rowItem.getTitle());
            ImageView imageView = (ImageView) convertView.findViewById(R.id.icon);
            imageView.setImageResource(rowItem.getImageId());
            return convertView;
        }

Suggestion in your getView() put a check for (convertview == null). It might not have any impact on this small adapter but in case your adapter is having more items, it will impact the performance.

EDIT To put your spinner dropdown below the anchor, use

android:overlapAnchor="false" inside your spinner

Fulbright answered 14/3, 2016 at 9:5 Comment(9)
i updated ur code but images are not loading from array-ListNorthcliffe
ok ok only images not loading from arraylist that's my problemNorthcliffe
hi did u check problem?Northcliffe
check the answer nowFulbright
means when i tapped on spinner button then spinner list have to show below of that title i hope u understandNorthcliffe
yes yes but i want to show spinner list like below of that spinner titleNorthcliffe
android:overlapAnchor="false"Fulbright
actually i am begginer for android when i click button then process is same for showing spinner listNorthcliffe
Let us continue this discussion in chat.Fulbright
L
40

Change your adapter like this

public class CustomAdapter extends ArrayAdapter<RowItem> {

    LayoutInflater flater;

    public CustomAdapter(Activity context, int resouceId, int textviewId, List<RowItem> list){

        super(context,resouceId,textviewId, list);
//        flater = context.getLayoutInflater();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        return rowview(convertView,position);
    }

    @Override
    public View getDropDownView(int position, View convertView, ViewGroup parent) {
        return rowview(convertView,position);
    }

    private View rowview(View convertView , int position){

        RowItem rowItem = getItem(position);

        viewHolder holder ;
        View rowview = convertView;
        if (rowview==null) {

            holder = new viewHolder();
            flater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            rowview = flater.inflate(R.layout.listitems_layout, null, false);

            holder.txtTitle = (TextView) rowview.findViewById(R.id.title);
            holder.imageView = (ImageView) rowview.findViewById(R.id.icon);
            rowview.setTag(holder);
        }else{
            holder = (viewHolder) rowview.getTag();
        }
        holder.imageView.setImageResource(rowItem.getImageId());
        holder.txtTitle.setText(rowItem.getTitle());

        return rowview;
    }

    private class viewHolder{
        TextView txtTitle;
        ImageView imageView;
    }
}
Lorrettalorri answered 14/3, 2016 at 10:30 Comment(1)
Legacy View Holder pattern ;D Vote upUnlike
F
30

Inside your adapter constructor, send the id of textview also

public CustomAdapter(Activity context,int resouceId, int textviewId, List<RowItem> list){

        super(context,resouceId,textviewId, list);
        flater = context.getLayoutInflater();
    }

call it by

CustomAdapter adapter = new CustomAdapter(MainActivity.this,
                R.layout.listitems_layout, R.id.title, rowItems);

EDIT Your images are not showing because you didn't override the getDropdownView() method. This method decides the layout of child when dropdown is visible. So add this method to your adapter

@Override
        public View getDropDownView(int position, View convertView, ViewGroup parent) {
            if(convertView == null){
                convertView = flater.inflate(R.layout.list_itemslayout,parent, false);
            }
            RowItem rowItem = getItem(position);
            TextView txtTitle = (TextView) convertView.findViewById(R.id.title);
            txtTitle.setText(rowItem.getTitle());
            ImageView imageView = (ImageView) convertView.findViewById(R.id.icon);
            imageView.setImageResource(rowItem.getImageId());
            return convertView;
        }

Suggestion in your getView() put a check for (convertview == null). It might not have any impact on this small adapter but in case your adapter is having more items, it will impact the performance.

EDIT To put your spinner dropdown below the anchor, use

android:overlapAnchor="false" inside your spinner

Fulbright answered 14/3, 2016 at 9:5 Comment(9)
i updated ur code but images are not loading from array-ListNorthcliffe
ok ok only images not loading from arraylist that's my problemNorthcliffe
hi did u check problem?Northcliffe
check the answer nowFulbright
means when i tapped on spinner button then spinner list have to show below of that title i hope u understandNorthcliffe
yes yes but i want to show spinner list like below of that spinner titleNorthcliffe
android:overlapAnchor="false"Fulbright
actually i am begginer for android when i click button then process is same for showing spinner listNorthcliffe
Let us continue this discussion in chat.Fulbright
P
-2

We can also use ViewHolder Pattern

public class TypeAdapter extends ArrayAdapter<RowItem> {
    public TypeAdapter(@NonNull Context context, ArrayList<Calendar> objects) {
        super(context, R.layout.calendar_type_row, objects);
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        return rowView(convertView, position);
    }

    @Override
    public View getDropDownView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        return rowView(convertView, position);
    }

    class ViewHolder extends RecyclerView.ViewHolder {
        //Views
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            //Init Views by itemView.findViewById
        }
    }

    private View rowView(View convertView, int position) {
        if(convertView==null)
        {
          convertView = LayoutInflater.from(getContext()).inflate(R.layout.calendar_type_row,null);
        }
        RowItem rowType = getItem(position);
        ViewHolder viewHolder = new ViewHolder(convertView);
        //Setup Values
        return convertView;
    }
}
Poore answered 1/6, 2020 at 5:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.