使用自定义适配器的Listview无法在SherlockFragment中工作

时间:2013-07-30 11:16:56

标签: android listview adapter

适配器:

public class ServerAdapter extends ArrayAdapter<Server>
{
    private Context Context; 
    private int ResourceId;    
    private List<Server> Data = null;

    public ServerAdapter(Context context, int layoutResourceId, List<Server> data)
    {
        super(context, layoutResourceId, data);
        ResourceId = layoutResourceId;
        Context = context;
        Data = data;
    }

    public void updateServersList(List<Server> newlist)
    {
        Data.clear();
        Data = newlist;
        this.notifyDataSetChanged();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        View Row = convertView;
        ViewHolder Holder = null;
        Server server = Data.get(position);
        if(Row == null)
        {
            LayoutInflater inflater = ((Activity)Context).getLayoutInflater();
            Row = inflater.inflate(ResourceId, parent, false);

            Holder = new ViewHolder();          
            Holder.Hostname = (TextView)convertView.findViewById(R.id.hostname);
            Holder.Address = (TextView)convertView.findViewById(R.id.address);
            Holder.Players = (TextView)convertView.findViewById(R.id.players);
            Holder.Photo = (ImageView) convertView.findViewById(R.id.imageView1);   
            Row.setTag(Holder);
        }
        else
        {           
            Holder = (ViewHolder) Row.getTag();
        }

        Holder.Hostname.setText(server.getHostname());
        Holder.Address.setText("Address: " + server.getIp() + ":" + server.getPort());
        Holder.Players.setText("Players: " + server.getPlayers() + "/" + server.getMaxPlayers());
        Holder.Photo.setImageResource(server.getGameObject().getImageResId());
        return Row;
    }
}

class ViewHolder
{
   TextView Hostname;
   TextView Address;
   TextView Players;
   ImageView Photo;
}

SherlockFragment:

public class Favourites extends SherlockFragment
{   
    public static ListView FavoritesListView;
    public static ServerAdapter FavoritesAdapter;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View v = inflater.inflate(R.layout.servers, null);

        FavoritesListView = (ListView) v.findViewById(R.id.serverlistview);
        FavoritesAdapter = new ServerAdapter(this.getSherlockActivity(), R.layout.server, DataHandler.getUserFavoriteServersFromLocal());        
        FavoritesListView.setAdapter(FavoritesAdapter);
        return v;
    }
}

servers.xml

<?xml version="1.0" encoding="utf-8"?>
<ListView    
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/serverlistview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
</ListView>

server.xml中

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <RelativeLayout
        android:id="@+id/RelativeLayout1"
        android:layout_width="55dp"
        android:layout_height="59dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="6dp"
        android:orientation="vertical" >

        <ImageView
            android:id="@+id/imageView1"
            android:layout_width="55dp"
            android:layout_height="55dp"
            android:layout_marginTop="4dp"
            android:contentDescription="@string/game"
            android:src="@drawable/game" />
    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/relativeLayout2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="0dp"   
        android:layout_toRightOf="@+id/RelativeLayout1"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/hostname"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="0dp"
            android:paddingLeft="5dp"
            android:text="@string/hostname"
            android:textSize="18sp"
            android:textStyle="bold"
            android:ellipsize="end"
            android:singleLine="true" />
    </RelativeLayout>

    <TextView
        android:id="@+id/address"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/relativeLayout2"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/relativeLayout2"
        android:paddingLeft="5dp"
        android:text="@string/address" />

    <TextView
        android:id="@+id/players"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/address"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/address"
        android:paddingLeft="5dp"
        android:text="@string/players" />       
</RelativeLayout>

错误:

  

07-30 13:11:38.824:E / AndroidRuntime(31423):致命异常:主要   07-30 13:11:38.824:E / AndroidRuntime(31423):   java.lang.NullPointerException 07-30 13:11:38.824:   E / AndroidRuntime(31423):at   com.example.app.ServerAdapter.getView(ServerAdapter.java:47)   07-30 13:11:38.824:E / AndroidRuntime(31423):at   android.widget.AbsListView.obtainView(AbsListView.java:2159)07-30   13:11:38.824:E / AndroidRuntime(31423):at   android.widget.ListView.makeAndAddView(ListView.java:1831)   ...

2 个答案:

答案 0 :(得分:1)

问题是由于片段生命周期的工作方式。在onCreateView实现中,您在创建适配器时引用片段的活动。问题是,在调用onActivityCreated之前,活动不会对片段可用。

如果查看fragment lifecycle as described here,您可以看到onCreateView后面是对onActivityCreated的调用。

尝试将onCreateView中的一些代码移动到onActivityCreated:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    View v = inflater.inflate(R.layout.servers, null);      
    FavoritesListView = (ListView) v.findViewById(R.id.serverlistview);
    return v;
}


@Override
public void onActivityCreated(Bundle savedInstanceState) {


    super.onActivityCreated(savedInstanceState);    

    FavoritesAdapter = new ServerAdapter(this.getSherlockActivity(), R.layout.servers, DataHandler.getUserFavoriteServersFromLocal());       
    FavoritesListView.setAdapter(FavoritesAdapter); 


}   

此外,您似乎在适配器的getView()代码中使用了错误的变量。您测试Row == null(这意味着convertView也为null),然后将Row指定为新膨胀视图的值。但是,然后尝试从convertView中查找子视图,该视图仍为空。

尝试编辑适配器的getView()方法,如下所示:

    @Override
public View getView(int position, View convertView, ViewGroup parent)
{
    View Row = convertView;
    ViewHolder Holder = null;
    Server server = Data.get(position);
    if(Row == null)
    {
        LayoutInflater inflater = ((Activity)Context).getLayoutInflater();
        Row = inflater.inflate(ResourceId, parent, false);

        Holder = new ViewHolder();          
        //Holder.Hostname = (TextView)convertView.findViewById(R.id.hostname);
        //Holder.Address = (TextView)convertView.findViewById(R.id.address);
        //Holder.Players = (TextView)convertView.findViewById(R.id.players);
        //Holder.Photo = (ImageView) convertView.findViewById(R.id.imageView1);   
        Holder.Hostname = (TextView)Row.findViewById(R.id.hostname);
        Holder.Address = (TextView)Row.findViewById(R.id.address);
        Holder.Players = (TextView)Row.findViewById(R.id.players);
        Holder.Photo = (ImageView)Row.findViewById(R.id.imageView1);  
        Row.setTag(Holder);
    }
    //etc
  }

答案 1 :(得分:0)

可能因为你正在使用布局来扩展Row,然后继续使用convertView来获取对象的引用?我不知道你的布局怎么样,只是一个建议。

View Row = convertView;
...
Row = inflater.inflate(ResourceId, parent, false); 
...       
Holder.Hostname = (TextView)convertView.findViewById(R.id.hostname);