如何使用适配器初始化ListActivity?

时间:2014-06-08 03:08:49

标签: android layout android-listview android-arrayadapter

我有一个Android项目,我希望用自定义编写的适配器将Activity转换为ListActivity

public class MyArrayAdapter extends ArrayAdapter<Coordinate> {
      private final Context context;
      private final List<Coordinate> values;

      public MyArrayAdapter(Context context, List<Coordinate> values) {
        super(context, R.layout.table_row, values);
        this.context = context;
        this.values = values;
    }

    @Override
      public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View rowView = inflater.inflate(R.layout.table_row, parent, false);

        TextView textViewRowId = (TextView) rowView.findViewById(R.id.table_row_id);
        TextView textViewLatitude = (TextView) rowView.findViewById(R.id.table_row_latitude);
        TextView textViewLongitude = (TextView) rowView.findViewById(R.id.table_row_longitude);
        TextView textViewAtitude = (TextView) rowView.findViewById(R.id.table_row_altitude);

        textViewRowId.setText(Long.toString(values.get(position).getId()));
        textViewLatitude.setText(Double.toString(values.get(position).getLatitude()));
        textViewLongitude.setText(Double.toString(values.get(position).getLongitude()));
        textViewAtitude.setText(Double.toString(values.get(position).getAltitude()));

        return rowView;
      }

    @Override
    public void add(Coordinate object) {
        super.add(object);
        values.add(object);
    }
}

问题在于初始化布局。我不知道首先要初始化/膨胀什么。在onCreate Activity的{​​{1}}中进行此操作:

public class MainActivity extends ListActivity implements ActionBar.TabListener {

    SectionsPagerAdapter mSectionsPagerAdapter;

    ViewPager mViewPager;

    protected static final int SECTION_MAIN = 1;
    protected static final int SECTION_DB_TABLE = 2;

    private LocationManager location_manger;
    private CoordinatesDataSource coordinates_data_source;

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

        coordinates_data_source = new CoordinatesDataSource(getApplicationContext());
        coordinates_data_source.open();
        List<Coordinate> values = coordinates_data_source.getAllCoordinates();
        MyArrayAdapter adapter = new MyArrayAdapter(getApplicationContext(), values);
        setListAdapter(adapter);

        // Set up the action bar.
        final ActionBar actionBar = getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        // Create the adapter that will return a fragment for each of the three
        // primary sections of the activity.
        mSectionsPagerAdapter = new SectionsPagerAdapter(getFragmentManager());

        // Set up the ViewPager with the sections adapter.
        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mSectionsPagerAdapter);

        // When swiping between different sections, select the corresponding tab. 
        // We can also use ActionBar.Tab#select() to do this if we have a reference to the Tab.
        mViewPager
                .setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
                    @Override
                    public void onPageSelected(int position) {
                        actionBar.setSelectedNavigationItem(position);
                    }
                });

        // For each of the sections in the app, add a tab to the action bar.
        for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
            // Create a tab with text corresponding to the page title defined by the adapter.
            // Also specify this Activity object, which implements the TabListener
            // interface, as the callback (listener) for when this tab is selected.
            actionBar.addTab(actionBar.newTab()
                    .setText(mSectionsPagerAdapter.getPageTitle(i))
                    .setTabListener(this));
        }       

        MyLocationListener loclist = new MyLocationListener(
                this, getApplicationContext(), coordinates_data_source);

        location_manger = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        location_manger.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 1, loclist);


    }
//...

在带有列表的片段中我只有这个:

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

</ListView>

有了这段代码,我会收到以下错误:

  8782         AndroidRuntime  E  FATAL EXCEPTION: main
  8782         AndroidRuntime  E  Process: pl.patryk, PID: 8782
  8782         AndroidRuntime  E  java.lang.RuntimeException: Unable to start activity ComponentInfo{pl.patryk/pl.patryk.MainActivity}: java.lang.RuntimeException: Your content mu
                               st have a ListView whose id attribute is 'android.R.id.list'
  8782         AndroidRuntime  E  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2215)
  8782         AndroidRuntime  E  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2265)
  8782         AndroidRuntime  E  at android.app.ActivityThread.access$800(ActivityThread.java:145)
  8782         AndroidRuntime  E  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1206)
  8782         AndroidRuntime  E  at android.os.Handler.dispatchMessage(Handler.java:102)
  8782         AndroidRuntime  E  at android.os.Looper.loop(Looper.java:136)
  8782         AndroidRuntime  E  at android.app.ActivityThread.main(ActivityThread.java:5144)
  8782         AndroidRuntime  E  at java.lang.reflect.Method.invokeNative(Native Method)
  8782         AndroidRuntime  E  at java.lang.reflect.Method.invoke(Method.java:515)
  8782         AndroidRuntime  E  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
  8782         AndroidRuntime  E  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:611)
  8782         AndroidRuntime  E  at dalvik.system.NativeStart.main(Native Method)
  8782         AndroidRuntime  E  Caused by: java.lang.RuntimeException: Your content must have a ListView whose id attribute is 'android.R.id.list'
  8782         AndroidRuntime  E  at android.app.ListActivity.onContentChanged(ListActivity.java:243)
  8782         AndroidRuntime  E  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:346)
  8782         AndroidRuntime  E  at android.app.Activity.setContentView(Activity.java:1929)
  8782         AndroidRuntime  E  at pl.patryk.MainActivity.onCreate(MainActivity.java:48)
  8782         AndroidRuntime  E  at android.app.Activity.performCreate(Activity.java:5231)
  8782         AndroidRuntime  E  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
  8782         AndroidRuntime  E  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2169)
  8782         AndroidRuntime  E  ... 11 more

如果我移动setContentView(R.layout.activity_main);,我会得到以下内容:

  8941         AndroidRuntime  E  FATAL EXCEPTION: main
  8941         AndroidRuntime  E  Process: pl.patryk, PID: 8941
  8941         AndroidRuntime  E  java.lang.RuntimeException: Unable to start activity ComponentInfo{pl.patryk/pl.patryk.MainActivity}: java.lang.NullPointerException
  8941         AndroidRuntime  E  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2215)
  8941         AndroidRuntime  E  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2265)
  8941         AndroidRuntime  E  at android.app.ActivityThread.access$800(ActivityThread.java:145)
  8941         AndroidRuntime  E  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1206)
  8941         AndroidRuntime  E  at android.os.Handler.dispatchMessage(Handler.java:102)
  8941         AndroidRuntime  E  at android.os.Looper.loop(Looper.java:136)
  8941         AndroidRuntime  E  at android.app.ActivityThread.main(ActivityThread.java:5144)
  8941         AndroidRuntime  E  at java.lang.reflect.Method.invokeNative(Native Method)
  8941         AndroidRuntime  E  at java.lang.reflect.Method.invoke(Method.java:515)
  8941         AndroidRuntime  E  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
  8941         AndroidRuntime  E  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:611)
  8941         AndroidRuntime  E  at dalvik.system.NativeStart.main(Native Method)
  8941         AndroidRuntime  E  Caused by: java.lang.NullPointerException
  8941         AndroidRuntime  E  at pl.patryk.MainActivity.onCreate(MainActivity.java:67)

修改

要明确: 我的activity_main.xml没有ListView。我有2个片段是我的标签,在一个(第二个标签)中我有上面添加的ListView

所以我的布局:

activity_main
fragment_main
fragment_table_points
table_row

activity_main是主要布局,fragment_main是第一个标签,fragment_table_points第二个标签,table_row是适配器的布局。

2 个答案:

答案 0 :(得分:3)

它是null,因为ListView id应该来自ListView的默认android id,而不是创建它的新id,因此给你这个错误:

Your content must have a ListView whose id attribute is 'android.R.id.list'

<强>问题:

android:id="@+id/list"

<强>溶液

更改id以匹配ListActivity的android listview id

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

</ListView>

答案 1 :(得分:0)

Rod_Algonquin提供了very good answer above,以便ListAdapter使用Activity。我需要将其与Fragment一起使用,因此我需要将Fragment类扩展为ListFragment并实现所需的方法。

public static class MyListFragment extends ListFragment{
    /**
     * The fragment argument representing the section number for this fragment.
     */
    private static final String ARG_SECTION_NUMBER = "section_number";

    /**
     * Returns a new instance of this fragment for the given section number.
     */
    public static MyListFragment newInstance(int sectionNumber) {
        MyListFragment fragment = new MyListFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_SECTION_NUMBER, sectionNumber);
        fragment.setArguments(args);
        return fragment;
    }

    public MyListFragment(){}

    @Override
    public View onCreateView(
            LayoutInflater inflater, 
            ViewGroup container,
            Bundle savedInstanceState) {
        int current_section = getArguments().getInt(ARG_SECTION_NUMBER);
        int current_layout;

        switch (current_section) {
        case SECTION_MAIN:
            current_layout = R.layout.fragment_main;
            break;
        default:
            current_layout = R.layout.fragment_other;
            break;
        }

        View rootView = inflater.inflate(current_layout, container, false);
        return rootView;
    }
}