带有自定义行的ListView会抛出InflaterException

时间:2014-06-27 19:10:37

标签: java android listview android-fragments android-listview

我尝试用里面的ListView构建一个Fragment。在活动开始时,应用程序崩溃并发生InflaterException。

我有一个自定义适配器,它应该将自定义行设计扩展到ListView中。你能帮我吗?

messagelistrow.xml

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/messageListRow"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/border"
    android:padding="6dp" >

    <ImageView
        android:id="@+id/icon"
        android:layout_width="50dip"
        android:layout_height="50dip"
        android:src="@drawable/ic_action_mail_blue"
        android:layout_alignParentLeft="true"
        android:layout_centerInParent="true"
        android:scaleType="center" 
        android:contentDescription="@string/messageImageDescription"/>

    <TextView
        android:id="@+id/messageDate"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_toRightOf="@id/icon"
        android:ellipsize="marquee"
        android:singleLine="true"
        android:textColor="#1e1e1e"
        android:textSize="@dimen/contentTextSize" />

    <TextView
        android:id="@+id/messageSnippet"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_toRightOf="@+id/icon"
        android:layout_marginLeft="2dip" />
</RelativeLayout> 

MessageListItem.java

public class MessageListItem {
    private String messageSnippet;
     private int iconId;
     private String date;

     public MessageListItem(String messageSnippet,  String date) {

      this.messageSnippet = messageSnippet;
      this.iconId = R.drawable.ic_action_mail_blue;
      this.date = date;
     }

     public String getMessageSnippet() {
      return messageSnippet;
     }

     public void setMessageSnippet(String messageSnippet) {
      this.messageSnippet = messageSnippet;
     }

     public int getIconId() {
      return iconId;
     }

     public void setIconId(int iconID) {
      this.iconId = iconID;
     }

     public String getMessageDate() {
      return date;
     }

     public void setMessageDate(String status) {
      this.date = status;
     }
}

MessageListAdapter.java

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

import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class MessageListAdapter extends BaseAdapter {

     Activity context;
     LayoutInflater inflater;
     ArrayList<Object> rowItems;

     public MessageListAdapter(Activity context, ArrayList<Object> rowItems) {
      this.context = context;
      this.rowItems = rowItems;
     }

     @Override
     public int getCount() {
      return rowItems.size();
     }

     @Override
     public Object getItem(int position) {
      return rowItems.get(position);
     }

     @Override
     public long getItemId(int position) {
      return rowItems.indexOf(getItem(position));
     }

     public static class ViewHolder {
            ImageView icon;
            TextView messageSnippet;
            TextView messageDate;
     }

     @Override
     public View getView(int position, View convertView, ViewGroup parent) {

         ViewHolder holder;
            if(convertView==null)
            {
                holder = new ViewHolder();
                convertView = inflater.inflate(R.layout.messagelistrow, null);

                holder.icon = (ImageView) convertView.findViewById(R.id.icon);
                holder.messageSnippet = (TextView) convertView.findViewById(R.id.messageSnippet);
                holder.messageDate = (TextView) convertView.findViewById(R.id.messageDate);

                convertView.setTag(holder);
            }
            else
                holder=(ViewHolder)convertView.getTag();

            MessageListItem ml = (MessageListItem) rowItems.get(position);

            holder.icon.setImageResource(ml.getIconId());
            holder.messageSnippet.setText(ml.getMessageSnippet());
            holder.messageDate.setText(ml.getMessageDate());

            return convertView;
        }

}

HistoryMessageListFragment.java

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

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.Toast;

public class HistoryMessageListFragment extends Fragment{

    private OnItemSelectedListener listener;
    String[] messageSnippets;
    Integer iconID;
    String[] messageDates;

    ArrayList<Object> messageListRowItems;
    ListView messageListView;
    MessageListItem item;

    @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container,
          Bundle savedInstanceState) {
          View view = inflater.inflate(R.layout.historylist, container, false);

          prepareArrayLits();
          messageListView = (ListView) view.findViewById(R.id.messageList);
          MessageListAdapter adapter = new MessageListAdapter(getActivity(), messageListRowItems);
          messageListView.setAdapter(adapter);
          messageListView.setOnItemClickListener(new OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position,
                        long id) {

                    String item = "Hallo";

                    Toast.makeText(getActivity(), item, Toast.LENGTH_LONG).show();
                }
          });
          return view;
      }

      public interface OnItemSelectedListener {
          public void onMessageSelected(String link);
        }

    @Override
    public void onAttach(Activity activity) {
      super.onAttach(activity);
      if (activity instanceof OnItemSelectedListener) {
        listener = (OnItemSelectedListener) activity;
      } else {
        throw new ClassCastException(activity.toString()
            + " must implemenet MyListFragment.OnItemSelectedListener");
      }
    }
     public void prepareArrayLits()
        {
            messageListRowItems = new ArrayList<Object>();

            AddObjectToList(R.drawable.ic_action_mail_blue, 
                    getResources().getStringArray(R.array.messageSnippets)[0], 
                    getResources().getStringArray(R.id.messageDate)[0]);
        }

        // Add one item into the Array List
        public void AddObjectToList(int image, String messageSnippet, String messageDate)
        {
            item = new MessageListItem(messageSnippet, messageDate);
            item.setIconId(image);
            messageListRowItems.add(item);
        }
  // May also be triggered from the Activity
  public void updateDetail() {
    // create fake data
    String newTime = String.valueOf(System.currentTimeMillis());
    // Send data to Activity
    listener.onMessageSelected(newTime);
  }
}

HistoryMessageListActivity.java

package o2.telefonica.mma.ABHC;

import o2.telefonica.mma.ABHC.settings.Results;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class HistoryMessageListActivity extends Activity implements
    MenuItem.OnMenuItemClickListener, HistoryMessageListFragment.OnItemSelectedListener{

    private MenuItem action_about;
    private MenuItem action_exit;
    private MenuItem action_settings;
    private MenuItem action_newMessage;
    private MenuItem action_delete;
    private MenuItem action_search;

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

  @Override
  public void onMessageSelected(String link) {
    HistoryMessageFragment fragment = (HistoryMessageFragment) getFragmentManager()
        .findFragmentById(R.id.detailFragment);
    if (fragment != null && fragment.isInLayout()) {
      fragment.setMessageText(link);
    } else {
      Intent intent = new Intent(getApplicationContext(), HistoryMessageActivity.class);
      intent.putExtra(HistoryMessageActivity.EXTRA_URL, link);
      startActivityForResult(intent, Results.START_ACTIVITY);

    }
  }


  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
      getMenuInflater().inflate(R.menu.history_activity_actions, menu);
      this.action_about = menu.findItem(R.id.action_about);
      this.action_about.setOnMenuItemClickListener(this);
      this.action_exit = menu.findItem(R.id.action_exit);
      this.action_exit.setOnMenuItemClickListener(this);
      this.action_settings = menu.findItem(R.id.action_settings);
      this.action_settings.setOnMenuItemClickListener(this);
      this.action_newMessage = menu.findItem(R.id.action_newMessage);
      this.action_newMessage.setOnMenuItemClickListener(this);
      this.action_delete = menu.findItem(R.id.action_delete);
      this.action_delete.setOnMenuItemClickListener(this);
      this.action_search = menu.findItem(R.id.action_search);
      this.action_search.setOnMenuItemClickListener(this);
      return super.onCreateOptionsMenu(menu);
  }

  @Override
  public boolean onMenuItemClick(MenuItem item) {
      if (item.getItemId() == R.id.action_delete) {
          //TODO Delete Message
          return true;
      } else if (item.getItemId() == R.id.action_newMessage) {
          //setContentView(R.layout.history);
          finish();
          //new HistoryController(this, R.layout.history, m);
          return true;
      } else if (item.getItemId() == R.id.action_about) {
          //setContentView(R.layout.about);
        startActivityForResult(new Intent(this, AboutActivity.class), Results.START_ACTIVITY);
          //new AboutController(this, R.layout.about, m);
          return true;
      } else if (item.getItemId() == R.id.action_settings) {
          //setContentView(R.layout.settings);
          startActivityForResult(new Intent(this, SettingsActivity.class), Results.START_ACTIVITY);
          //new SettingsController(this, R.layout.settings, m);
          return true;
      } else if (item.getItemId() == R.id.action_exit) {
          //TODO exit
          return true;
      } else if (item.getItemId() == R.id.action_search) {
          //TODO search function
          return true;
      }
      return false;
  }
} 

historylist.xml(片段布局)

<?xml version="1.0" encoding="utf-8"?>  
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/historyView"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_gravity="top"
    android:background="@null"
    android:gravity="center"
    android:orientation="vertical"
    android:paddingBottom="12dp"
    android:paddingLeft="21dp"
    android:paddingRight="21dp"
    android:paddingTop="12dp" >

    <TextView
        android:id="@+id/historyMessagesListLabel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:paddingBottom="@dimen/spacingLabelToText"
        android:text="@string/historyMessagesLabel"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textColor="#ffffff"
        android:textSize="@dimen/titleTextSize" />

    <ListView
        android:id="@+id/messageList"
        android:layout_width="450dp"
        android:layout_height="fill_parent"
        android:layout_alignParentBottom="true"
        android:layout_below="@+id/historyMessagesListLabel"
        android:layout_centerHorizontal="true"
        android:background="@drawable/textfieldshape"
        android:minWidth="450dp"
        android:textColor="#ffffff" >

    </ListView>

</RelativeLayout> 

logcat(更新)

06-27 21:44:32.685: I/Timeline(7980): Timeline: Activity_idle id: android.os.BinderProxy@64b28c80 time:113147909
06-27 21:44:35.137: I/Timeline(7980): Timeline: Activity_launch_request id:o2.telefonica.mma.ABHC time:113150356
06-27 21:44:35.197: I/art(7980): GcCauseBackground partial concurrent mark sweep GC freed 14537(802KB) AllocSpace objects, 2(32KB) LOS objects, 6% free, 13MB/14MB, paused 12.451ms total 76.324ms
06-27 21:44:35.708: I/Timeline(7980): Timeline: Activity_idle id: android.os.BinderProxy@64b91c10 time:113150926
06-27 21:44:37.109: I/Timeline(7980): Timeline: Activity_launch_request id:o2.telefonica.mma.ABHC time:113152336
06-27 21:44:37.149: E/ActivityThread(7980): Failed to inflate
06-27 21:44:37.149: E/ActivityThread(7980): android.view.InflateException: Binary XML file line #8: Error inflating class fragment
06-27 21:44:37.149: E/ActivityThread(7980):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:713)
06-27 21:44:37.149: E/ActivityThread(7980):     at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
06-27 21:44:37.149: E/ActivityThread(7980):     at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
06-27 21:44:37.149: E/ActivityThread(7980):     at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
06-27 21:44:37.149: E/ActivityThread(7980):     at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
06-27 21:44:37.149: E/ActivityThread(7980):     at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:343)
06-27 21:44:37.149: E/ActivityThread(7980):     at android.app.Activity.setContentView(Activity.java:1929)
06-27 21:44:37.149: E/ActivityThread(7980):     at o2.telefonica.mma.ABHC.HistoryMessageListActivity.onCreate(HistoryMessageListActivity.java:23)
06-27 21:44:37.149: E/ActivityThread(7980):     at android.app.Activity.performCreate(Activity.java:5231)
06-27 21:44:37.149: E/ActivityThread(7980):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
06-27 21:44:37.149: E/ActivityThread(7980):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2167)
06-27 21:44:37.149: E/ActivityThread(7980):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2262)
06-27 21:44:37.149: E/ActivityThread(7980):     at android.app.ActivityThread.access$800(ActivityThread.java:145)
06-27 21:44:37.149: E/ActivityThread(7980):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1206)
06-27 21:44:37.149: E/ActivityThread(7980):     at android.os.Handler.dispatchMessage(Handler.java:102)
06-27 21:44:37.149: E/ActivityThread(7980):     at android.os.Looper.loop(Looper.java:136)
06-27 21:44:37.149: E/ActivityThread(7980):     at android.app.ActivityThread.main(ActivityThread.java:5137)
06-27 21:44:37.149: E/ActivityThread(7980):     at java.lang.reflect.Method.invoke(Native Method)
06-27 21:44:37.149: E/ActivityThread(7980):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
06-27 21:44:37.149: E/ActivityThread(7980):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:611)
06-27 21:44:37.149: E/ActivityThread(7980): Caused by: java.lang.NullPointerException
06-27 21:44:37.149: E/ActivityThread(7980):     at java.lang.VMClassLoader.findLoadedClass(Native Method)
06-27 21:44:37.149: E/ActivityThread(7980):     at java.lang.ClassLoader.findLoadedClass(ClassLoader.java:362)
06-27 21:44:37.149: E/ActivityThread(7980):     at java.lang.ClassLoader.loadClass(ClassLoader.java:499)
06-27 21:44:37.149: E/ActivityThread(7980):     at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
06-27 21:44:37.149: E/ActivityThread(7980):     at android.app.Fragment.instantiate(Fragment.java:583)
06-27 21:44:37.149: E/ActivityThread(7980):     at android.app.Fragment.instantiate(Fragment.java:561)
06-27 21:44:37.149: E/ActivityThread(7980):     at android.app.Activity.onCreateView(Activity.java:4778)
06-27 21:44:37.149: E/ActivityThread(7980):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:689)
06-27 21:44:37.149: E/ActivityThread(7980):     ... 19 more
06-27 21:44:37.149: D/AndroidRuntime(7980): Shutting down VM
06-27 21:44:37.159: E/AndroidRuntime(7980): FATAL EXCEPTION: main
06-27 21:44:37.159: E/AndroidRuntime(7980): Process: o2.telefonica.mma.ABHC, PID: 7980
06-27 21:44:37.159: E/AndroidRuntime(7980): java.lang.RuntimeException: Unable to start activity ComponentInfo{o2.telefonica.mma.ABHC/o2.telefonica.mma.ABHC.HistoryMessageListActivity}: android.view.InflateException: Binary XML file line #8: Error inflating class fragment
06-27 21:44:37.159: E/AndroidRuntime(7980):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2213)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2262)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at android.app.ActivityThread.access$800(ActivityThread.java:145)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1206)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at android.os.Handler.dispatchMessage(Handler.java:102)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at android.os.Looper.loop(Looper.java:136)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at android.app.ActivityThread.main(ActivityThread.java:5137)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at java.lang.reflect.Method.invoke(Native Method)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:611)
06-27 21:44:37.159: E/AndroidRuntime(7980): Caused by: android.view.InflateException: Binary XML file line #8: Error inflating class fragment
06-27 21:44:37.159: E/AndroidRuntime(7980):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:713)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:343)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at android.app.Activity.setContentView(Activity.java:1929)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at o2.telefonica.mma.ABHC.HistoryMessageListActivity.onCreate(HistoryMessageListActivity.java:23)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at android.app.Activity.performCreate(Activity.java:5231)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2167)
06-27 21:44:37.159: E/AndroidRuntime(7980):     ... 9 more
06-27 21:44:37.159: E/AndroidRuntime(7980): Caused by: java.lang.NullPointerException
06-27 21:44:37.159: E/AndroidRuntime(7980):     at java.lang.VMClassLoader.findLoadedClass(Native Method)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at java.lang.ClassLoader.findLoadedClass(ClassLoader.java:362)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at java.lang.ClassLoader.loadClass(ClassLoader.java:499)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at android.app.Fragment.instantiate(Fragment.java:583)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at android.app.Fragment.instantiate(Fragment.java:561)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at android.app.Activity.onCreateView(Activity.java:4778)
06-27 21:44:37.159: E/AndroidRuntime(7980):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:689)
06-27 21:44:37.159: E/AndroidRuntime(7980):     ... 19 more

history.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal"
    android:baselineAligned="false" >

    <fragment
        android:id="@+id/listFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_gravity="top"
        android:layout_weight="1" />

    <fragment
        android:id="@+id/detailFragment"
        android:layout_width="0dp"
        android:layout_weight="2"
        android:layout_height="match_parent" />
</LinearLayout> 

如果您需要更多信息,请随时提出。

提前致谢。

1 个答案:

答案 0 :(得分:0)

你的问题在这里:

convertView = inflater.inflate(R.layout.messagelistrow, null);

您未在代码中初始化inflater

你需要:

 inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
在getView方法中

,所以getView方法必须是:

@Override
     public View getView(int position, View convertView, ViewGroup parent) {

         ViewHolder holder;
            if(convertView==null)
            {
                inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

                holder = new ViewHolder();
                convertView = inflater.inflate(R.layout.messagelistrow, null);

                holder.icon = (ImageView) convertView.findViewById(R.id.icon);
                holder.messageSnippet = (TextView) convertView.findViewById(R.id.messageSnippet);
                holder.messageDate = (TextView) convertView.findViewById(R.id.messageDate);

                convertView.setTag(holder);
            }
            else
                holder=(ViewHolder)convertView.getTag();

            MessageListItem ml = (MessageListItem) rowItems.get(position);

            holder.icon.setImageResource(ml.getIconId());
            holder.messageSnippet.setText(ml.getMessageSnippet());
            holder.messageDate.setText(ml.getMessageDate());

            return convertView;
        }

另一个问题是历史xml文件:第8行

Binary XML file line #8: Error inflating class fragment

您需要将fragment更改为FrameLayout