Android ListView适配器加载错误

时间:2014-04-18 11:24:04

标签: android android-listview android-adapter

由于某种原因,当我使用此代码时,它无法正常工作。

,而不是将每个十字路口放在其位置,而是将最后一个放在第一个,其余的都是空的。

package com.Itay.lightalaram.lightalarm;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

public class CrossroadsActivity extends Activity {
    private List<Crossroad> crossroads;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.crossroads);

        crossroads = new ArrayList<Crossroad>();

        populateListView();
    }

    private void populateListView() {
        ListView list = (ListView) findViewById(R.id.crossroadsListView);
        crossroads.add(new Crossroad("Oranim", 50, 30));
        crossroads.add(new Crossroad("Evelina", 40, 85));
        crossroads.add(new Crossroad("Sacker", 43, 22));
        crossroads.add(new Crossroad("bagger", 43, 22));


        ArrayAdapter<Crossroad> adapter = new CrossroadAdapter();

        list.setAdapter(adapter);
    }

    private class CrossroadAdapter extends ArrayAdapter<Crossroad> {
        public CrossroadAdapter(){
            super(CrossroadsActivity.this, R.layout.item_crossroad, crossroads);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View itemView = convertView;
            if(null == itemView) {
                itemView = getLayoutInflater().inflate(R.layout.item_crossroad, parent, false);

                Crossroad currentCrossroad = crossroads.get(position);

                TextView name = (TextView) findViewById(R.id.item_crossroadName);
                TextView redLight = (TextView) findViewById(R.id.item_redLightDuration);
                TextView greenLight = (TextView) findViewById(R.id.item_greenLightDuration);
                try {
                    name.setText(currentCrossroad.getName());
                    redLight.setText("" + currentCrossroad.getRedLight());
                    greenLight.setText("" + currentCrossroad.getGreenLight());
                } catch (Exception e) {
                }
                return itemView;
            }
            return null;
        }
    }
}

输出:

3 个答案:

答案 0 :(得分:1)

 private class CrossroadAdapter extends ArrayAdapter<Crossroad> {
    public CrossroadAdapter() {
        super(MainActivity.this, R.layout.item_crossroad, crossroads);
    }

    TextView name, redLight, greenLight;

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View itemView = convertView;
        Crossroad currentCrossroad = crossroads.get(position);
        if (null == itemView) {
            itemView = getLayoutInflater().inflate(R.layout.item_crossroad,
                    parent, false);

            name = (TextView) itemView
                    .findViewById(R.id.item_crossroadName);
            redLight = (TextView) itemView
                    .findViewById(R.id.item_redLightDuration);
            greenLight = (TextView) itemView
                    .findViewById(R.id.item_greenLightDuration);

        }
        try {
            name.setText(currentCrossroad.getName());
            redLight.setText("" + currentCrossroad.getRedLight());
            greenLight.setText("" + currentCrossroad.getGreenLight());
        } catch (Exception e) {
        }
        return itemView;
    }
}

答案 1 :(得分:1)

<强>解释
出现此问题的原因是,当您convertView的条件为null时,您只设置了一次充气布局。但是,在第一次itemView ins {t} null之后。除第一个项目外,您的项目不会更新。此外,您需要返回列表项的所有视图( itemView )。

<强>解决方案
在适配器中,getView方法需要对布局进行膨胀(一次)并返回此布局:

// inflate the layout to the row (items)
View itemView = convertView;
if(null == itemView) {
    itemView = getLayoutInflater().inflate(R.layout.item_crossroad, parent, false);
}
// Then return the inflated view and all its stuff
return itemView;

此外,您需要将所有项目的视图附加到布局,如下所示:

 // itemView.findViewById(...) to retrieve the id which is on the inflated layout
 TextView name = (TextView) itemView.findViewById(R.id.item_crossroadName);

最后,为了提高Adapter的效果,您应该使用ViewHolder。这将避免您永远调用所有findViewById方法。这是great tutoriala simple example。然后,您的方法可能是:

 // Init your variables
 public ViewHolder {
     TextView name, redLight, greenLight
 }

 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
      View itemView = convertView;
      // create the ViewHolder variable
      ViewHolderItem viewHolder;

      if(itemView == null) {
           itemView = getLayoutInflater().inflate(R.layout.item_crossroad, parent, false);

           // create a new ViewHolder
           viewHolder = new ViewHolderItem();

           // get your views with the ViewHolder and attached to the inflated layout
           viewHolder.name = (TextView) itemView.findViewById(R.id.item_crossroadName);
           viewHolder.redLight = (TextView) itemView.findViewById(R.id.item_redLightDuration);
           viewHolder.greenLight = (TextView) itemView.findViewById(R.id.item_greenLightDuration);

           // store the ViewHolder
           itemView.setTag(viewHolder);
     }else{
         // this is not the first, reuse the stored ViewHolder
         viewHolder = (ViewHolderItem) convertView.getTag();
     }

     // do your stuff...
     Crossroad currentCrossroad = crossroads.get(position);
     try {
         viewHolder.name.setText(currentCrossroad.getName());
         viewHolder.redLight.setText("" + currentCrossroad.getRedLight());
         viewHolder.greenLight.setText("" + currentCrossroad.getGreenLight());
     } catch (Exception e) { }

     // return the layout inflated
     return itemView;
}  

答案 2 :(得分:0)

将getview方法更改为

public View getView(int position, View convertView, ViewGroup parent) {
View itemView = convertView;
if(null == itemView) {
    itemView = getLayoutInflater().inflate(R.layout.item_crossroad, parent, false);
}
    Crossroad currentCrossroad = crossroads.get(position);

    TextView name = (TextView) itemView.findViewById(R.id.item_crossroadName);
    TextView redLight = (TextView) itemView.findViewById(R.id.item_redLightDuration);
    TextView greenLight = (TextView) itemView.findViewById(R.id.item_greenLightDuration);

    name.setText(currentCrossroad.getName());
    redLight.setText("" + currentCrossroad.getRedLight());
    greenLight.setText("" + currentCrossroad.getGreenLight());

    return itemView;         

}

对结果进行评论