Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
268 views
in Technique[技术] by (71.8m points)

listview - Android : App Crash When scrolling List View with 2 Different Cells

I want to implement the two cells type in my app Image and text so i'm just testing this, my app works fine and load perfectly but tis crashes when i start scrolling with the following error

java.lang.ArrayIndexOutOfBoundsException: length=2; index=2130968624

this is my adapter

  public class myadapter extends ArrayAdapter<myobject> {

    Context context;
    List<myobject> objectlist;


    public myadapter(Context context, int resource, List<myobject> objects) {
        super(context, resource, objects);
        this.context = context;
        this.objectlist = objects;
    }

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

        ViewHolder2 tvholder;
        ViewHolder ivholder;

        LayoutInflater inflater =(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        if (getItemViewType(position) == R.layout.textcell){

            if(convertView==null){
                convertView= inflater.inflate(getItemViewType(position),parent,false);
                tvholder= new ViewHolder2(convertView);
                convertView.setTag(tvholder);
            }else{
                tvholder = (ViewHolder2)convertView.getTag();
            }
            tvholder.TV.setText(objectlist.get(position).getText());
        }else{
            if(convertView==null){
                convertView= inflater.inflate(getItemViewType(position),parent,false);
                ivholder = new ViewHolder(convertView);
                convertView.setTag(ivholder);
            }else{
               ivholder=(ViewHolder) convertView.getTag();
            }
            ivholder.IV.setImageResource(objectlist.get(position).getImage());
        }
        return convertView;
    }

    @Override
    public int getViewTypeCount() {
        return 2;
    }

    @Override
    public int getItemViewType(int position) {
        if(objectlist.get(position).getType()==1){
            return R.layout.textcell;

        }else{
            return R.layout.imagecell;
        }
    }

}
class ViewHolder{
    ImageView IV;

    public ViewHolder(View view){
        IV = (ImageView)view.findViewById(R.id.IV);


    }

}
class ViewHolder2{

    TextView TV;
    public ViewHolder2(View view){

        TV = (TextView)view.findViewById(R.id.TV);

    }

}

my object :

public class myobject {

    int type;
    String Text;
    int Image;
    public myobject(){
        this.type = 0;
        this.Text = null;
        this.Image = 0;
    }
    public myobject(int type,String Text,int Image){
        this.type=type;
        this.Image = Image;
        this.Text = Text;
    }
    public int getType(){ return type;}
    public String getText (){return Text;}
    public int getImage (){return Image;}
}

Use in Main Activity :

public class MainActivity extends AppCompatActivity {

ListView LV;
List<myobject> myobjectList = new ArrayList<>();
myadapter myadapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    LV = (ListView) findViewById(R.id.LV);
    myobject myobject1 = new myobject(1,"teeeeeexxxxt",0);
    myobject myobject2 = new myobject(2,null,R.mipmap.ic_launcher);
    myobject myobject3 = new myobject(1,"teeeeeexxxxt",0);
    myobject myobject4 = new myobject(1,"teeeeeexxxxt",0);
    myobject myobject5 = new myobject(2,null,R.mipmap.ic_launcher);
    myobject myobject6 = new myobject(2,null,R.mipmap.ic_launcher);
    myobject myobject7 = new myobject(2,null,R.mipmap.ic_launcher);
    myobject myobject8 = new myobject(1,"teeeeeexxxxt",0);
    myobject myobject9 = new myobject(1,"teeeeeexxxxt",0);
    myobjectList.add(myobject1);
    myobjectList.add(myobject2);
    myobjectList.add(myobject3);
    myobjectList.add(myobject4);
    myobjectList.add(myobject5);
    myobjectList.add(myobject6);
    myobjectList.add(myobject7);
    myobjectList.add(myobject8);
    myobjectList.add(myobject9);
    myadapter = new myadapter(this,0,myobjectList);
    LV.setAdapter(myadapter);
}

I really don't know what is causing this fatal error + is my implementation consider to be the most optimize approach for the 2 different cells type ?

any ideas would be much appreciated

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Before solving your issue I want to clarify something first. While using the ArrayAdapter you don't have to store yourself the list of objects or the context, since it is done for you when the adapter is created. that being said, every call like objectlist.get(position) would be something like this getItem(position), and to obtain the context you simply call getContext.

Now let's explore the issue. According to Adapter class documentation, the getItemViewType(int position) method has to return a value between 0 and getViewTypeCount() - 1.

An integer representing the type of View. Two views should share the same type if one can be converted to the other in getView(int, View, ViewGroup). Note: Integers must be in the range 0 to getViewTypeCount() - 1. IGNORE_ITEM_VIEW_TYPE can also be returned.

The problem in you code is that you are returning the id of a layout file, which usually is a very big number, and thus IndexOutOfBounds is thrown. A possible solution for this would be to return the getItem(position).getType() - 1 instead of what you are currently returning. After this, the getView method can be changed to match the different layouts and view holders.

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

    ViewHolder2 tvholder;
    ViewHolder ivholder;

    LayoutInflater inflater =(LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    if (convertView == null) {
        switch (getItemViewType(position)) {
            case 0:
                convertView = inflater.inflate(R.layout.textcell, null);
                tvholder  = new ViewHolder2(convertView);
                tvholder.TV.setText(getItem(position).getText());
                convertView.setTag(tvholder);
                break;
            case 1:
                convertView = inflater.inflate(R.layout.imagecell, null);
                ivholder  = new ViewHolder(convertView);
                ivholder.IV.setImageResource(getItem(position).getImage());
                convertView.setTag(ivholder);
                break;
        }
    } else {
        switch (getItemViewType(position)) {
            case 0:
                tvholder = (ViewHolder2) convertView.getTag();
                tvholder.TV.setText(getItem(position).getText());
                break;
            case 1:
                ivholder = (ViewHolder) convertView.getTag();
                ivholder.IV.setImageResource(getItem(position).getImage());
                break;
        }
    }
    return convertView;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.8k users

...