通过片段中的自定义适配器更新listView

时间:2014-11-09 22:36:05

标签: android android-fragments android-arrayadapter listadapter

我正在尝试在我的Android应用程序中创建一个消息传递系统。当用户进入消息片段时,我需要使用上一条消息填充消息列表。根据我的阅读,最好的方法是使用自定义适配器。

这是我的消息适配器

public class MessageAdapter extends ArrayAdapter<message>  {
private final MessagesFragment context;
private final int layoutResourceId;
private final ArrayList<message> messages;

public MessageAdapter(MessagesFragment messagesFragment, int layoutResourceId, ArrayList<message> messages) {
    super(null, layoutResourceId);
    this.context = messagesFragment;
    this.layoutResourceId = layoutResourceId;
    this.messages = messages;

}
@Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
    View row = convertView;
    ViewHolder  holder = null;
    int direction = messages.get(i).userType;
    //show message on left or right, depending on if
    //it's incoming or outgoing

    if (row == null) {
        LayoutInflater inflater = ((MessagesFragment)context).getLayoutInflater(); 

        int res = 0;
        if (direction == DIRECTION_INCOMING) {
            res = R.layout.message_right;
        } else if (direction == DIRECTION_OUTGOING) {
            res = R.layout.message_left;
        }    
        convertView = inflater.inflate(res, viewGroup, false);
        holder = new ViewHolder();
        holder.txtMessage = (TextView) convertView.findViewById(R.id.txtMessage);
        holder.txtDate = (TextView) convertView.findViewById(R.id.txtDate);
        row.setTag(holder);
    }

     holder.txtMessage.setText(messages.get(i).message);
     holder.txtDate.setText(messages.get(i).time);

     return row;
}

static class ViewHolder
{
    TextView txtMessage;
    TextView txtDate;
}

}

我在片段中的onCreateView中调用了这个。

        // Generates all of the messages
    ArrayList<message> messages = getMessages;
    View messagesView = inflater.inflate(R.layout.messages, container, false);
    ListView listView = (ListView)messagesView.findViewById(R.id.listMessages);
    listView.setAdapter(new MessageAdapter(MessagesFragment.this, R.id.listMessages, messages));
    ...

每当我输入片段时,我的应用程序都会崩溃。我已经采用了一些示例代码并应用于我的应用程序,但我无法让它工作。我没有看到任何建议或明显的错误?

3 个答案:

答案 0 :(得分:0)

看起来你的设计方式错了 - 你的MessageAdapter会将片段作为参考。相反,您的活动应该创建并使用您的片段,并在您的片段中,实例化您的适配器并执行它应该做的任何事情,例如检索填充列表的消息数据。 因此,您的活动的上下文将传递给您的片段 - 然后使用相同的上下文传递到您的自定义适配器的构造函数。

答案 1 :(得分:0)

片段中的

更改:

 listView.setAdapter(new MessageAdapter(MessagesFragment.this, R.id.listMessages, messages));

 listView.setAdapter(new MessageAdapter(MessagesFragment.this.getActivity(), R.id.listMessages, messages));
适配器中的

更改:

private final MessagesFragment context;

    public MessageAdapter(MessagesFragment messagesFragment, int layoutResourceId, ArrayList<message> messages) {
        super(null, layoutResourceId);
        this.context = messagesFragment;
        this.layoutResourceId = layoutResourceId;
        this.messages = messages;
}

private final Context context;

public MessageAdapter(Context context, int layoutResourceId, ArrayList<message> messages) {
        super(context, layoutResourceId);
        this.context = context;
        this.layoutResourceId = layoutResourceId;
        this.messages = messages;
}

答案 2 :(得分:0)

public class MessageAdapter extends ArrayAdapter<message>  {
private final MessagesFragment context;
private final int layoutResourceId;
private final ArrayList<message> messages;

public MessageAdapter(MessagesFragment messagesFragment, int layoutResourceId, ArrayList<message> messages) {
    super(null, layoutResourceId);
    this.context = messagesFragment;
    this.layoutResourceId = layoutResourceId;
    this.messages = messages;

}
@Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
    View row = convertView;
    ViewHolder  holder = null;
    int direction = messages.get(i).userType;
    //show message on left or right, depending on if
    //it's incoming or outgoing

    if (row == null) {
        LayoutInflater inflater = ((MessagesFragment)context).getLayoutInflater(); 

        int res = 0;
        if (direction == DIRECTION_INCOMING) {
            res = R.layout.message_right;
        } else if (direction == DIRECTION_OUTGOING) {
            res = R.layout.message_left;
        }    
        convertView = inflater.inflate(res, viewGroup, false);
        holder = new ViewHolder();
        holder.txtMessage = (TextView) convertView.findViewById(R.id.txtMessage);
        holder.txtDate = (TextView) convertView.findViewById(R.id.txtDate);
        row.setTag(holder);
    }
     //You have get tag every time else it will through NullPointerException
     holder = (ViewHolder)row.getTag();
     holder.txtMessage.setText(messages.get(i).message);
     holder.txtDate.setText(messages.get(i).time);

     return row;
}

static class ViewHolder
{
    TextView txtMessage;
    TextView txtDate;
}

检查上面的代码,你犯了一些错误我已经弄错了。