1

Fragment で ExpandableListView を膨張させ、setAdapter を使用しようとしています。フラグメントで使用しない場合は適切に成功しますが、フラグメントではエラー (NullPointerException) が発生するか、ExpandableListView にデータが取り込まれません。

package com.stylingandroid.basicactionbar;

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

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ExpandableListView;

public class Friends extends Fragment
{
    private static List<Country> Countries;
    private ExpandableListView expandableListView;
    private CountryAdapter adapter;
    private View V;


    @Override
    public View onCreateView( LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState )
    {

        V = inflater.inflate( R.layout.frag2, container, false );
        LoadCountries();
        expandableListView = (ExpandableListView) V.findViewById(R.id.expandableListView);
        expandableListView.setAdapter(adapter);
        adapter = new CountryAdapter(this, Countries);

        return V;
    }


    private void LoadCountries() {
        Countries = new ArrayList<Country>();

        ArrayList<String> citiesAustralia = new ArrayList<String>(
                Arrays.asList("Brisbane", "Hobart", "Melbourne", "Sydney"));
        Countries.add(new Country("Australia", citiesAustralia));

        ArrayList<String> citiesChina = new ArrayList<String>(
                Arrays.asList("Beijing", "Chuzhou", "Dongguan", "Shangzhou"));
        Countries.add(new Country("China", citiesChina));
    }
    }

frag2.xml:

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

package com.stylingandroid.basicactionbar;



import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends Activity
{
    private class MyTabListener implements ActionBar.TabListener
    {
        private Fragment mFragment;
        private final Activity mActivity;
        private final String mFragName;

        public MyTabListener( Activity activity, String fragName )
        {
            mActivity = activity;
            mFragName = fragName;
        }

        @Override
        public void onTabReselected( Tab tab, FragmentTransaction ft )
        {
            // TODO Auto-generated method stub

        }

        @Override
        public void onTabSelected( Tab tab, FragmentTransaction ft )
        {
            mFragment = Fragment.instantiate( mActivity, mFragName );
            ft.add( android.R.id.content, mFragment );
        }

        @Override
        public void onTabUnselected( Tab tab, FragmentTransaction ft )
        {
            ft.remove( mFragment );
            mFragment = null;
        }
    }

    @Override
    public void onCreate( Bundle savedInstanceState )
    {
        super.onCreate( savedInstanceState );       
        Intent intent;

        ActionBar ab = getActionBar();
        ab.setNavigationMode( ActionBar.NAVIGATION_MODE_TABS );

        Tab tab = ab.newTab()
                .setText( R.string.title_param )
                .setTabListener( 
                        new MyTabListener( this, 
                                Param.class.getName() ) );
        ab.addTab( tab );

        intent = new Intent().setClass(this, Friends.class);
        tab = ab.newTab()
                .setText( R.string.title_friends )


                .setTabListener( 
                        new MyTabListener( this, 
                                Friends.class.getName() ) );
        ab.addTab( tab );

        tab = ab.newTab()
                .setText( R.string.title_maps )
                .setTabListener( 
                        new MyTabListener( this, 
                                Maps.class.getName() ) );
        ab.addTab( tab );
    }

    @Override
    public boolean onCreateOptionsMenu( Menu menu )
    {
        getMenuInflater().inflate( R.menu.main, menu );
        return true;
    }

    @Override
    public boolean onOptionsItemSelected( MenuItem item )
    {
        boolean ret;
        if (item.getItemId() == R.id.menu_settings)
        {
            // Handle Settings
            ret = true;
        } else
        {
            ret = super.onOptionsItemSelected( item );
        }
        return ret;
    }
}

国アダプタ:

package com.stylingandroid.basicactionbar;

import android.R;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;

import java.util.List;

public class CountryAdapter extends BaseExpandableListAdapter {
    private List<Country> countries;
    private LayoutInflater inflater;

    public CountryAdapter(Context context) {
        this.countries = countries;
        inflater = LayoutInflater.from(context);
    }

    public CountryAdapter(Friends friends, List<Country> countries2) {
        // TODO Auto-generated constructor stub
    }

    @Override
    public int getGroupCount() {
        return countries.size();
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        return countries.get(groupPosition).getCities().size();
    }

    @Override
    public Object getGroup(int groupPosition) {
        return countries.get(groupPosition).getName();
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return countries.get(groupPosition).getCities().get(childPosition);
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.simple_expandable_list_item_1, parent, false);
        }

        ((TextView) convertView).setText(getGroup(groupPosition).toString());
        return convertView;
    }

    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        if(convertView == null) {
            convertView = inflater.inflate(R.layout.simple_list_item_1, parent, false);
        }

        ((TextView)convertView).setText(getChild(groupPosition,childPosition).toString());
        return convertView;
    }

    @Override
    public boolean isChildSelectable(int i, int i2) {
        return false;
    }
}

間違っている部分は次のとおりです。

public CountryAdapter(Context context) {
    this.countries = countries;
    inflater = LayoutInflater.from(context);
}

問題は、フラグメント Friends に (Context, context) を使用する方法がわからないことです。何か案が?

前もって感謝します!:)

編集:

Gaurav Vashisth のコードを使用したところ、NullPointerException が発生しました。これがスタックトレースです。

10-12 19:11:52.105: D/dalvikvm(2203): GC_FOR_ALLOC freed 41K, 6% free 2553K/2716K, paused 62ms, total 66ms
10-12 19:11:52.116: I/dalvikvm-heap(2203): Grow heap (frag case) to 3.215MB for 635812-byte allocation
10-12 19:11:52.265: D/dalvikvm(2203): GC_FOR_ALLOC freed 1K, 6% free 3172K/3340K, paused 141ms, total 141ms
10-12 19:11:52.525: D/dalvikvm(2203): GC_CONCURRENT freed <1K, 5% free 3178K/3340K, paused 8ms+176ms, total 264ms
10-12 19:11:53.405: D/libEGL(2203): loaded /system/lib/egl/libEGL_emulation.so
10-12 19:11:53.495: D/(2203): HostConnection::get() New Host Connection established 0x2a155620, tid 2203
10-12 19:11:53.616: D/libEGL(2203): loaded /system/lib/egl/libGLESv1_CM_emulation.so
10-12 19:11:53.625: D/libEGL(2203): loaded /system/lib/egl/libGLESv2_emulation.so
10-12 19:11:53.725: W/EGL_emulation(2203): eglSurfaceAttrib not implemented
10-12 19:11:53.766: D/OpenGLRenderer(2203): Enabling debug mode 0
10-12 19:12:11.858: D/AndroidRuntime(2203): Shutting down VM
10-12 19:12:11.858: W/dalvikvm(2203): threadid=1: thread exiting with uncaught exception (group=0x40a71930)
10-12 19:12:11.906: E/AndroidRuntime(2203): FATAL EXCEPTION: main
10-12 19:12:11.906: E/AndroidRuntime(2203): java.lang.NullPointerException
10-12 19:12:11.906: E/AndroidRuntime(2203):     at com.stylingandroid.basicactionbar.CountryAdapter.getGroupCount(CountryAdapter.java:26)
10-12 19:12:11.906: E/AndroidRuntime(2203):     at android.widget.ExpandableListConnector.getCount(ExpandableListConnector.java:397)
10-12 19:12:11.906: E/AndroidRuntime(2203):     at android.widget.ListView.setAdapter(ListView.java:462)
10-12 19:12:11.906: E/AndroidRuntime(2203):     at android.widget.ExpandableListView.setAdapter(ExpandableListView.java:470)
10-12 19:12:11.906: E/AndroidRuntime(2203):     at com.stylingandroid.basicactionbar.Friends.onCreateView(Friends.java:32)
10-12 19:12:11.906: E/AndroidRuntime(2203):     at android.app.Fragment.performCreateView(Fragment.java:1695)
10-12 19:12:11.906: E/AndroidRuntime(2203):     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:885)
10-12 19:12:11.906: E/AndroidRuntime(2203):     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1057)
10-12 19:12:11.906: E/AndroidRuntime(2203):     at android.app.BackStackRecord.run(BackStackRecord.java:682)
10-12 19:12:11.906: E/AndroidRuntime(2203):     at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1435)
10-12 19:12:11.906: E/AndroidRuntime(2203):     at android.app.FragmentManagerImpl$1.run(FragmentManager.java:441)
10-12 19:12:11.906: E/AndroidRuntime(2203):     at android.os.Handler.handleCallback(Handler.java:725)
10-12 19:12:11.906: E/AndroidRuntime(2203):     at android.os.Handler.dispatchMessage(Handler.java:92)
10-12 19:12:11.906: E/AndroidRuntime(2203):     at android.os.Looper.loop(Looper.java:137)
10-12 19:12:11.906: E/AndroidRuntime(2203):     at android.app.ActivityThread.main(ActivityThread.java:5041)
10-12 19:12:11.906: E/AndroidRuntime(2203):     at java.lang.reflect.Method.invokeNative(Native Method)
10-12 19:12:11.906: E/AndroidRuntime(2203):     at java.lang.reflect.Method.invoke(Method.java:511)
10-12 19:12:11.906: E/AndroidRuntime(2203):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
10-12 19:12:11.906: E/AndroidRuntime(2203):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
10-12 19:12:11.906: E/AndroidRuntime(2203):     at dalvik.system.NativeStart.main(Native Method)
10-12 19:17:12.528: I/Process(2203): Sending signal. PID: 2203 SIG: 9

編集 2: 次のコードを使用すると、NullPointerException が発生し、上記のスタック トレースが変更されます。

@Override
public View onCreateView( LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState )
{

    LoadCountries();
    V = inflater.inflate( R.layout.frag2, container, false );
    expandableListView = (ExpandableListView) V.findViewById(R.id.expandableListView);

    adapter = new CountryAdapter(getActivity(), Countries);
    expandableListView.setAdapter(adapter);
    return V;
}

国アダプタ:

private List<Country> countries;
private LayoutInflater inflater;

public CountryAdapter(Context context, List<Country> contries) {
    this.countries = countries;
    inflater = LayoutInflater.from(context);
}
4

2 に答える 2

0

onCreateView メソッドで、初期化する前にアダプター メソッドを使用していることがわかります。このように使用してください

@Override
public View onCreateView( LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState )
{

    V = inflater.inflate( R.layout.frag2, container, false );
    LoadCountries();
    expandableListView = (ExpandableListView) V.findViewById(R.id.expandableListView);

    adapter = new CountryAdapter(getActivity(), Countries);
    expandableListView.setAdapter(adapter);
    return V;
}

フラグメント内のアクティビティの参照を取得するには、getActivity() を使用します

それ以外にも

アダプターのコンストラクターが次のようになるように

public CountryAdapter(Context context, List<Country> countries) {
    this.countries = countries;
    inflater = LayoutInflater.from(context);
}

また、Java の規則に従って、メソッド名は小文字で始まることも指摘したいと思います。LoadCountries()に名前を変更していただければ幸いです。loadCountries()

于 2013-10-12T18:30:45.197 に答える
0

使用するgetActivity()

public final Activity getActivity ()

Added in API level 11
Return the Activity this fragment is currently associated with.

交換

  adapter = new CountryAdapter(this, Countries);

  adapter = new CountryAdapter(getActivity(), Countries);

また、逆にする必要があります

 expandableListView.setAdapter(adapter);
 adapter = new CountryAdapter(this, Countries);

 adapter = new CountryAdapter(getActivity(), Countries);
 expandableListView.setAdapter(adapter);

編集:

また、に変更する方が良いでしょう

  private void LoadCountries() {
    Countries = new ArrayList<Country>();

    ArrayList<String> citiesAustralia = new ArrayList<String>(
            Arrays.asList("Brisbane", "Hobart", "Melbourne", "Sydney"));
    Countries.add(new Country("Australia", citiesAustralia));

    ArrayList<String> citiesChina = new ArrayList<String>(
            Arrays.asList("Beijing", "Chuzhou", "Dongguan", "Shangzhou"));
    Countries.add(new Country("China", citiesChina));
    adapter = new CountryAdapter(getActivity(), Countries);
    expandableListView.setAdapter(adapter);

   }
于 2013-10-12T18:27:25.137 に答える