自定义ExpandableListView示例

时间:2014-06-25 14:08:30

标签: android custom-controls expandablelistview

我正在尝试使用自定义组和列表布局实现自定义ExpandableListView。 我跟着this guide并研究了其他例子。但是,我得到了这个例外:

抛出java.lang.ClassNotFoundException

你知道我做错了吗?

完成LogCat

android.view.InflateException: Binary XML file line #24: Class is not a View com.jws.rapp.DeparturesExpandableListView
            at android.view.LayoutInflater.createView(LayoutInflater.java:611)
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:696)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
            at com.jws.rapp.DeparturesFragment.onCreateView(DeparturesFragment.java:35)
            at android.app.Fragment.performCreateView(Fragment.java:1695)
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:885)
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1057)
            at android.app.BackStackRecord.run(BackStackRecord.java:682)
            at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1435)
            at android.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:474)
            at android.support.v13.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:167)
            at android.support.v4.view.ViewPager.populate(ViewPager.java:1068)
            at android.support.v4.view.ViewPager.populate(ViewPager.java:914)
            at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1436)
            at android.view.View.measure(View.java:15848)
            at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:728)
            at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:477)
            at android.view.View.measure(View.java:15848)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5008)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
            at android.view.View.measure(View.java:15848)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5008)
            at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
            at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
            at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
            at android.view.View.measure(View.java:15848)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5008)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
            at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2189)
            at android.view.View.measure(View.java:15848)
            at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1905)
            at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1104)
            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1284)
            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1004)
            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5481)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
            at android.view.Choreographer.doCallbacks(Choreographer.java:562)
            at android.view.Choreographer.doFrame(Choreographer.java:532)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
            at android.os.Handler.handleCallback(Handler.java:730)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5103)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.ClassCastException: com.jws.rapp.DeparturesExpandableListView cannot be cast to android.view.View
            at java.lang.Class.asSubclass(Class.java:1182)
            at android.view.LayoutInflater.createView(LayoutInflater.java:559)
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:696)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
            at com.jws.rapp.DeparturesFragment.onCreateView(DeparturesFragment.java:35)
            at android.app.Fragment.performCreateView(Fragment.java:1695)
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:885)
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1057)
            at android.app.BackStackRecord.run(BackStackRecord.java:682)
            at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1435)
            at android.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:474)
            at android.support.v13.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:167)
            at android.support.v4.view.ViewPager.populate(ViewPager.java:1068)
            at android.support.v4.view.ViewPager.populate(ViewPager.java:914)
            at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1436)
            at android.view.View.measure(View.java:15848)
            at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:728)
            at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:477)
            at android.view.View.measure(View.java:15848)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5008)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
            at android.view.View.measure(View.java:15848)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5008)
            at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
            at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
            at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
            at android.view.View.measure(View.java:15848)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5008)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
            at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2189)
            at android.view.View.measure(View.java:15848)
            at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1905)
            at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1104)
            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1284)
            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1004)
            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5481)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
            at android.view.Choreographer.doCallbacks(Choreographer.java:562)
            at android.view.Choreographer.doFrame(Choreographer.java:532)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
            at android.os.Handler.handleCallback(Handler.java:730)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5103)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
            at dalvik.system.NativeStart.main(Native Method)

小组

import java.util.ArrayList;

public class DepartureOverview {
    private String route;
    private String destination;
    private int timeToDeparture;

    // ArrayList to store child objects
    private ArrayList<DepartureDetails> children;

    public String getRoute()
    {
        return route;
    }

    public void setRoute(String route)
    {
        this.route = route;
    }
    public String getDestination()
    {
        return destination;
    }

    public void setDestination(String destination)
    {
        this.destination = destination;
    }

    public int getTimeToDeparture()
    {
        return timeToDeparture;
    }

    public void setTimeToDeparture(int timeToDeparture)
    {
        this.timeToDeparture = timeToDeparture;
    }

    // ArrayList to store child objects
    public ArrayList<DepartureDetails> getChildren()
    {
        return children;
    }

    public void setChildren(ArrayList<DepartureDetails> children)
    {
        this.children = children;
    }
}

孩子

public class DepartureDetails {
    private String name;
    private String text1;
    private String text2;

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public String getText1()
    {
        return text1;
    }

    public void setText1(String text1)
    {
        this.text1 = text1;
    }

    public String getText2()
    {
        return text2;
    }

    public void setText2(String text2)
    {
        this.text2 = text2;
    }
}

自定义ExpandableListActivity

public class DeparturesExpandableListView extends ExpandableListActivity {
    //Initialize variables
    private ArrayList<DepartureOverview> departures;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        /*Resources res = this.getResources();
        Drawable devider = res.getDrawable(R.drawable.line);

        // Set ExpandableListView values

        getExpandableListView().setGroupIndicator(null);
        getExpandableListView().setDivider(devider);
        getExpandableListView().setChildDivider(devider);
        getExpandableListView().setDividerHeight(1);
        registerForContextMenu(getExpandableListView());*/

        // Adding ArrayList data to ExpandableListView values
        loadHosts(buildDummyData());
    }

    private ArrayList<DepartureOverview> buildDummyData()
    {
        // Creating ArrayList of type parent class to store parent class objects
        final ArrayList<DepartureOverview> list = new ArrayList<DepartureOverview>();
        for (int i = 1; i < 4; i++)
        {
            //Create parent class object
            final DepartureOverview parent = new DepartureOverview();

            // Set values in parent class object
            parent.setRoute(i + "A");
            parent.setDestination("Søndervangen");
            parent.setTimeToDeparture((int) System.currentTimeMillis() / 1000);
            parent.setChildren(new ArrayList<DepartureDetails>());

            // Create Child class object
            final DepartureDetails child = new DepartureDetails();
            child.setName("" + i);
            child.setText1("Child 0");

            //Add Child class object to parent class object
            parent.getChildren().add(child);

            //Adding Parent class object to ArrayList
            list.add(parent);
        }
        return list;
    }



    private void loadHosts(final ArrayList<DepartureOverview> newDepartures)
    {
        if (newDepartures == null)
            return;

        departures = newDepartures;

        // Check for ExpandableListAdapter object
        if (this.getExpandableListAdapter() == null)
        {
            //Create ExpandableListAdapter Object
            final DeparturesExpandableListAdapter mAdapter = new DeparturesExpandableListAdapter(getApplicationContext(), departures);

            // Set Adapter to ExpandableList Adapter
            this.setListAdapter(mAdapter);
        }
        else
        {
            // Refresh ExpandableListView data
            ((DeparturesExpandableListAdapter)getExpandableListAdapter()).notifyDataSetChanged();
        }
    }
}

列表适配器

public class DeparturesExpandableListAdapter extends BaseExpandableListAdapter {
    private LayoutInflater inflater;
    private ArrayList<DepartureOverview> departures;
    Context context;

    public DeparturesExpandableListAdapter(Context context, ArrayList<DepartureOverview> departures)
    {
        this.context = context;
        inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
        this.departures = departures;
    }


    // This Function used to inflate parent rows view
    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parentView)
    {
        final DepartureOverview departure = departures.get(groupPosition);

        // Inflate grouprow.xml file for parent rows
        convertView = inflater.inflate(R.layout.view_departure_overview, parentView, false);

        // Get grouprow.xml file elements and set values
        ((TextView) convertView.findViewById(R.id.route)).setText(departure.getRoute());
        ((TextView) convertView.findViewById(R.id.destination)).setText(departure.getDestination());
        ((TextView) convertView.findViewById(R.id.departureIn)).setText(departure.getTimeToDeparture());

        return convertView;
    }


    // This Function used to inflate child rows view
    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
                             View convertView, ViewGroup parentView)
    {
        final DepartureOverview departureOverview = departures.get(groupPosition);
        final DepartureDetails departureDetails = departureOverview.getChildren().get(childPosition);

        // Inflate childrow.xml file for child rows
        convertView = inflater.inflate(R.layout.view_departure_details, parentView, false);

        return convertView;
    }


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

    //Call when child row clicked
    @Override
    public long getChildId(int groupPosition, int childPosition)
    {
        return childPosition;
    }

    @Override
    public int getChildrenCount(int groupPosition)
    {
        if(departures.get(groupPosition).getChildren() != null)
            return departures.get(groupPosition).getChildren().size();

        return 0;
    }


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

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

    //Call when parent row clicked
    @Override
    public long getGroupId(int groupPosition)
    {
        return groupPosition;
    }

    @Override
    public void notifyDataSetChanged()
    {
        // Refresh List rows
        super.notifyDataSetChanged();
    }

    @Override
    public boolean isEmpty()
    {
        return ((departures == null) || departures.isEmpty());
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition)
    {
        return true;
    }

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

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

用法

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.jws.rapp.Settings">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/departures"
        style="@style/Title"/>

    <TextView
        android:id="@+id/stationName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="test"
        style="@style/H1"
        android:gravity="center"
        android:layout_below="@id/title"/>

    <com.jws.rapp.DeparturesExpandableListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

    </com.jws.rapp.DeparturesExpandableListView>

</RelativeLayout>

0 个答案:

没有答案