Android:滚动具有2个不同单元格的列表视图时,应用程序崩溃 [英] Android : App Crash When scrolling List View with 2 Different Cells

查看:61
本文介绍了Android:滚动具有2个不同单元格的列表视图时,应用程序崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的应用程序的图像和文本中实现两个单元格类型,所以我只是在测试它,我的应用程序可以正常工作并且可以完美加载,但是当我开始滚动并显示以下错误时tis崩溃

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

这是我的适配器

  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);

    }

}

我的对象:

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;}
}

在主要活动中使用:

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);
}

我真的不知道是什么导致了此致命错误+我的实现被认为是针对2种不同单元格类型的最优化方法吗?

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 ?

任何想法都将不胜感激

推荐答案

在解决您的问题之前,我想先澄清一下.使用ArrayAdapter时,您不必自己存储对象或上下文列表,因为创建适配器后便会为您完成.话虽如此,每次调用objectlist.get(position)都会像这样getItem(position),而要获取上下文,您只需调用getContext.

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.

现在让我们来探讨这个问题.根据Adapter文档getItemViewType(int position)方法必须返回0getViewTypeCount() - 1之间的值.

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.

代表View类型的整数.如果可以在getView(int,View,ViewGroup)中将一个视图转换为另一个视图,则两个视图应该共享相同的类型.注意:整数必须在0到getViewTypeCount()的范围内-1.也可以返回IGNORE_ITEM_VIEW_TYPE.

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.

代码中的问题是您正在返回布局文件的id,通常这是一个非常大的数字,因此会抛出IndexOutOfBounds. 一个可能的解决方案是返回getItem(position).getType() - 1而不是您当前返回的内容.之后,可以更改getView方法以匹配不同的布局和视图持有人.

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;
}

这篇关于Android:滚动具有2个不同单元格的列表视图时,应用程序崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆