在自定义适配器中找不到ViewByID

时间:2013-11-16 17:20:49

标签: android android-adapter

我创建了自己的自定义适配器,扩展了Array Adapter:

public class AdapterGeoArea extends ArrayAdapter<GeoArea>{
    private Context _context;   
    private int resource;
    private ArrayList<GeoArea> _myGeoArea;

    public AdapterGeoArea(Context context, ArrayList<GeoArea> myGeoArea) {
        super(context, 0, myGeoArea);
        _context = context;
        _myGeoArea = myGeoArea;
    }

    public int getCount() {
        return _myGeoArea.size();
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        LinearLayout GeoAreaView;
        if (convertView == null) { 
            GeoAreaView = new LinearLayout(_context);
            LayoutInflater li = LayoutInflater.from(_context);
            convertView = li.inflate(R.layout.layout_geo_areas, null);
        }
        else {
            GeoAreaView = (LinearLayout) convertView;
        }

        GeoArea curGeoArea = _myGeoArea.get(position);

        TextView name = (TextView) GeoAreaView.findViewById(R.id.txtGeoAreaName);
        name.setText(curGeoArea.name);

        return convertView;
    }

    static class ViewHolder { 
        TextView name;
        RelativeLayout childContainer;
    }

    @Override
    public Filter getFilter() {
        return null;
    }
}

以下是我在主要方面的使用方法:

public class ActivityGeoAreas extends Activity {

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

        GeoArea.searchTerm =  "Bar & Grill";

        GeoArea torontoArea = new GeoArea("cityOfToronto");

        ArrayList<GeoArea> testList = new ArrayList<GeoArea>();
        testList.add(torontoArea);

        AdapterGeoArea adapter = new AdapterGeoArea(this, testList);

        ListView lv = (ListView) findViewById(R.id.textGeoArea);
        lv.setAdapter(adapter);

    }

}

除了这一行,一切似乎都很好:

 TextView name = (TextView) GeoAreaView.findViewById(R.id.textGeoArea);

以下是我定义布局的方式:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".ActivityGeoAreas" >

    <TextView
        android:id="@+id/textGeoArea"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:text="Choose Area"
        android:textAppearance="?android:attr/textAppearanceLarge" />


    <LinearLayout
        android:id="@+id/LinearLayoutGeoAreas"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/textGeoArea"
        android:layout_below="@+id/textGeoArea"
        android:orientation="vertical" >
        <ListView
            android:id="@+id/listViewGeoArea"
            android:layout_width="wrap_content"
            android:layout_height="match_parent" >
        </ListView>

    </LinearLayout>
</RelativeLayout>

它根本无法找到TextView textGeoArea并且此行变为null,我做错了什么?

2 个答案:

答案 0 :(得分:2)

更改此

TextView name = (TextView) GeoAreaView.findViewById(R.id.txtGeoAreaName);

TextView name = (TextView) convertView.findViewById(R.id.txtGeoAreaName);

我猜你很困惑。

将textview移至新版面list_item.xml

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

<TextView
    android:id="@+id/textGeoArea"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="14dp"
    android:text="Choose Area"
    android:textAppearance="?android:attr/textAppearanceLarge" />

</RelativeLayout>

现在更改您的getView,如下所示

 LayoutInflater inflater;
 public AdapterGeoArea(Context context, ArrayList<GeoArea> myGeoArea) {
    super(context, 0, myGeoArea);
    _context = context;
    _myGeoArea = myGeoArea;
    inflater = LayoutInflater.from(context); // initialize inflater
}


 public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {  
            convertView = inflater.inflate(R.layout.list_row,parent,false);
            holder = new ViewHolder();
            holder.tv = (TextView)convertView.findViewById(R.id.textGeoArea); 
            holder.setTag(convertView);

        }
        else { 
                holder = (ViewHolder) convertView.getTag(); 
        } 
        GeoArea curGeoArea = _myGeoArea.get(position);
        holder.tv.setText(curGeoArea.name);

        return convertView;
    }

static class ViewHolder  // use a view holder for smooth scrolling an performance
{
TextView tv;
}

答案 1 :(得分:1)

在第一次通过时,GeoAreaView是一个没有孩子的LinearLayout,因为你刚刚创建它。 convertView View已初始化您的layout,其中包含TextView。因此,您需要使用它来查找TextView

TextView name = (TextView) convertView.findViewById(R.id.txtGeoAreaName);

我看到你有一个ViewHolder,但你似乎没有使用它。您可能需要花一点时间阅读有关使用ListView的详细教程。

This guy usually seems to have good tutorials