我使用了从 Eclipse“Master/Detail”布局创建的基本布局。我已经对其进行了修改并添加了外部页面。但是,当我现在尝试仅加载 ContactListActivity.java 时,它无法加载给我下面的 logcat 错误。关于我做错了什么的任何想法?
ContactListActivity.java
package com.cyphrd.chirpd;
import com.cyphrd.chirpd.R;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.view.MenuItem;
/**
* An activity representing a list of Contacts. This activity
* has different presentations for handset and tablet-size devices. On
* handsets, the activity presents a list of items, which when touched,
* lead to a {@link ContactChatActivity} representing
* item details. On tablets, the activity presents the list of items and
* item details side-by-side using two vertical panes.
* <p>
* The activity makes heavy use of fragments. The list of items is a
* {@link ContactListFragment} and the item details
* (if present) is a {@link ContactChatFragment}.
* <p>
* This activity also implements the required
* {@link ContactListFragment.Callbacks} interface
* to listen for item selections.
*/
public class ContactListActivity extends FragmentActivity
implements ContactListFragment.Callbacks {
/**
* Whether or not the activity is in two-pane mode, i.e. running on a tablet
* device.
*/
private boolean mTwoPane;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contact_list);
if (findViewById(R.id.contact_detail_container) != null) {
// The detail container view will be present only in the
// large-screen layouts (res/values-large and
// res/values-sw600dp). If this view is present, then the
// activity should be in two-pane mode.
mTwoPane = true;
// In two-pane mode, list items should be given the
// 'activated' state when touched.
((ContactListFragment) getSupportFragmentManager()
.findFragmentById(R.id.contact_list))
.setActivateOnItemClick(true);
}
// TODO: If exposing deep links into your app, handle intents here.
}
/**
* Callback method from {@link ContactListFragment.Callbacks}
* indicating that the item with the given ID was selected.
*/
@Override
public void onItemSelected(String id) {
if (mTwoPane) {
// In two-pane mode, show the detail view in this activity by
// adding or replacing the detail fragment using a
// fragment transaction.
Bundle arguments = new Bundle();
arguments.putString(ContactChatFragment.ARG_ITEM_ID, id);
ContactChatFragment fragment = new ContactChatFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.replace(R.id.contact_detail_container, fragment)
.commit();
} else {
// In single-pane mode, simply start the detail activity
// for the selected item ID.
Intent detailIntent = new Intent(this, ContactChatActivity.class);
detailIntent.putExtra(ContactChatFragment.ARG_ITEM_ID, id);
startActivity(detailIntent);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add("Search")
.setIcon(R.drawable.ic_search)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
menu.add("Add Contact")
.setIcon(R.drawable.ic_add_person)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
menu.add("Settings").setIcon(R.drawable.ic_settings);
//Whatever else is under the "More" menu
return true;
}
}
ContactListFragment.java
package com.cyphrd.chirpd;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.cyphrd.chirpd.dummy.DummyContent;
/**
* A list fragment representing a list of Contacts. This fragment
* also supports tablet devices by allowing list items to be given an
* 'activated' state upon selection. This helps indicate which item is
* currently being viewed in a {@link ContactChatFragment}.
* <p>
* Activities containing this fragment MUST implement the {@link Callbacks}
* interface.
*/
public class ContactListFragment extends ListFragment {
/**
* The serialization (saved instance state) Bundle key representing the
* activated item position. Only used on tablets.
*/
private static final String STATE_ACTIVATED_POSITION = "activated_position";
/**
* The fragment's current callback object, which is notified of list item
* clicks.
*/
private Callbacks mCallbacks = sDummyCallbacks;
/**
* The current activated item position. Only used on tablets.
*/
private int mActivatedPosition = ListView.INVALID_POSITION;
/**
* A callback interface that all activities containing this fragment must
* implement. This mechanism allows activities to be notified of item
* selections.
*/
public interface Callbacks {
/**
* Callback for when an item has been selected.
*/
public void onItemSelected(String id);
}
/**
* A dummy implementation of the {@link Callbacks} interface that does
* nothing. Used only when this fragment is not attached to an activity.
*/
private static Callbacks sDummyCallbacks = new Callbacks() {
@Override
public void onItemSelected(String id) {
}
};
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public ContactListFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// TODO: replace with a real list adapter.
setListAdapter(new ArrayAdapter<DummyContent.DummyItem>(
getActivity(),
android.R.layout.simple_list_item_activated_1,
android.R.id.text1,
DummyContent.ITEMS));
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Restore the previously serialized activated item position.
if (savedInstanceState != null
&& savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) {
setActivatedPosition(savedInstanceState.getInt(STATE_ACTIVATED_POSITION));
}
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// Activities containing this fragment must implement its callbacks.
if (!(activity instanceof Callbacks)) {
throw new IllegalStateException("Activity must implement fragment's callbacks.");
}
mCallbacks = (Callbacks) activity;
}
@Override
public void onDetach() {
super.onDetach();
// Reset the active callbacks interface to the dummy implementation.
mCallbacks = sDummyCallbacks;
}
@Override
public void onListItemClick(ListView listView, View view, int position, long id) {
super.onListItemClick(listView, view, position, id);
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (mActivatedPosition != ListView.INVALID_POSITION) {
// Serialize and persist the activated item position.
outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition);
}
}
/**
* Turns on activate-on-click mode. When this mode is on, list items will be
* given the 'activated' state when touched.
*/
public void setActivateOnItemClick(boolean activateOnItemClick) {
// When setting CHOICE_MODE_SINGLE, ListView will automatically
// give items the 'activated' state when touched.
getListView().setChoiceMode(activateOnItemClick
? ListView.CHOICE_MODE_SINGLE
: ListView.CHOICE_MODE_NONE);
}
private void setActivatedPosition(int position) {
if (position == ListView.INVALID_POSITION) {
getListView().setItemChecked(mActivatedPosition, false);
} else {
getListView().setItemChecked(position, true);
}
mActivatedPosition = position;
}
}
布局的 XML:
活动联系人列表:
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/contact_list"
android:name="com.cyphrd.chirp.ContactListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
tools:context=".ContactListActivity"
tools:layout="@android:layout/list_content" />
activity_contact_twopane.xml
<!--
This layout is a two-pane layout for the Contacts
master/detail flow. See res/values-large/refs.xml and
res/values-sw600dp/refs.xml for an example of layout aliases
that replace the single-pane version of the layout with
this two-pane version.
For more on layout aliases, see:
http://developer.android.com/training/multiscreen/screensizes.html#TaskUseAliasFilters
-->
<fragment
android:id="@+id/contact_list"
android:name="com.cyphrd.chirp.ContactListFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
tools:layout="@android:layout/list_content" />
<FrameLayout
android:id="@+id/contact_detail_container"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3" />
</LinearLayout>
日志猫:
12-08 15:11:31.978: E/AndroidRuntime(7071): FATAL EXCEPTION: main
12-08 15:11:31.978: E/AndroidRuntime(7071): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.cyphrd.chirpd/com.cyphrd.chirpd.ContactListActivity}: android.view.InflateException: Binary XML file line #1: Error inflating class fragment
12-08 15:11:31.978: E/AndroidRuntime(7071): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2049)
12-08 15:11:31.978: E/AndroidRuntime(7071): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2083)
12-08 15:11:31.978: E/AndroidRuntime(7071): at android.app.ActivityThread.access$600(ActivityThread.java:134)
12-08 15:11:31.978: E/AndroidRuntime(7071): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1233)
12-08 15:11:31.978: E/AndroidRuntime(7071): at android.os.Handler.dispatchMessage(Handler.java:99)
12-08 15:11:31.978: E/AndroidRuntime(7071): at android.os.Looper.loop(Looper.java:137)
12-08 15:11:31.978: E/AndroidRuntime(7071): at android.app.ActivityThread.main(ActivityThread.java:4697)
12-08 15:11:31.978: E/AndroidRuntime(7071): at java.lang.reflect.Method.invokeNative(Native Method)
12-08 15:11:31.978: E/AndroidRuntime(7071): at java.lang.reflect.Method.invoke(Method.java:511)
12-08 15:11:31.978: E/AndroidRuntime(7071): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:787)
12-08 15:11:31.978: E/AndroidRuntime(7071): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:554)
12-08 15:11:31.978: E/AndroidRuntime(7071): at dalvik.system.NativeStart.main(Native Method)
12-08 15:11:31.978: E/AndroidRuntime(7071): Caused by: android.view.InflateException: Binary XML file line #1: Error inflating class fragment
12-08 15:11:31.978: E/AndroidRuntime(7071): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:697)
12-08 15:11:31.978: E/AndroidRuntime(7071): at android.view.LayoutInflater.inflate(LayoutInflater.java:466)
12-08 15:11:31.978: E/AndroidRuntime(7071): at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
12-08 15:11:31.978: E/AndroidRuntime(7071): at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
12-08 15:11:31.978: E/AndroidRuntime(7071): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:255)
12-08 15:11:31.978: E/AndroidRuntime(7071): at android.app.Activity.setContentView(Activity.java:1879)
12-08 15:11:31.978: E/AndroidRuntime(7071): at com.cyphrd.chirpd.ContactListActivity.onCreate(ContactListActivity.java:39)
12-08 15:11:31.978: E/AndroidRuntime(7071): at android.app.Activity.performCreate(Activity.java:4539)
12-08 15:11:31.978: E/AndroidRuntime(7071): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
12-08 15:11:31.978: E/AndroidRuntime(7071): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2013)
12-08 15:11:31.978: E/AndroidRuntime(7071): ... 11 more
12-08 15:11:31.978: E/AndroidRuntime(7071): Caused by: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.cyphrd.chirp.ContactListFragment: make sure class name exists, is public, and has an empty constructor that is public
12-08 15:11:31.978: E/AndroidRuntime(7071): at android.support.v4.app.Fragment.instantiate(Fragment.java:401)
12-08 15:11:31.978: E/AndroidRuntime(7071): at android.support.v4.app.Fragment.instantiate(Fragment.java:369)
12-08 15:11:31.978: E/AndroidRuntime(7071): at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:272)
12-08 15:11:31.978: E/AndroidRuntime(7071): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:669)
12-08 15:11:31.978: E/AndroidRuntime(7071): ... 20 more
12-08 15:11:31.978: E/AndroidRuntime(7071): Caused by: java.lang.ClassNotFoundException: com.cyphrd.chirp.ContactListFragment
12-08 15:11:31.978: E/AndroidRuntime(7071): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
12-08 15:11:31.978: E/AndroidRuntime(7071): at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
12-08 15:11:31.978: E/AndroidRuntime(7071): at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
12-08 15:11:31.978: E/AndroidRuntime(7071): at android.support.v4.app.Fragment.instantiate(Fragment.java:391)
12-08 15:11:31.978: E/AndroidRuntime(7071): ... 23 more
清单.xml:
<activity
android:name="com.cyphrd.chirpd.ContactListActivity"
android:label="@string/title_contact_list" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.cyphrd.chirpd.ContactChatActivity"
android:label="@string/title_contact_detail"
android:parentActivityName="com.cyphrd.chirpd.ContactListActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".ContactListActivity" />
</activity>