Android 当自定义类是MainActivity的嵌套类时,膨胀类时出错
我有一个可扩展列表,其中包含多个组,每个组包含一个子级,这是一个可扩展列表,其中包含多个组,每个组还包含一个子级,该子级包含另一个可扩展列表………..,以此类推Android 当自定义类是MainActivity的嵌套类时,膨胀类时出错,android,xml,expandablelistview,classnotfoundexception,Android,Xml,Expandablelistview,Classnotfoundexception,我有一个可扩展列表,其中包含多个组,每个组包含一个子级,这是一个可扩展列表,其中包含多个组,每个组还包含一个子级,该子级包含另一个可扩展列表………..,以此类推 03-17 23:37:30.508 1751-1751/com.multilevellist E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: com.multilevellist, PID: 1751 java.lang.ClassCastException: android.w
03-17 23:37:30.508 1751-1751/com.multilevellist E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.multilevellist, PID: 1751
java.lang.ClassCastException: android.widget.RelativeLayout$LayoutParams
cannot be cast to android.widget.AbsListView$LayoutParams
at android.widget.ListView.setupChild(ListView.java:1826)
at android.widget.ListView.makeAndAddView(ListView.java:1793)
at android.widget.ListView.fillDown(ListView.java:691)
at android.widget.ListView.fillSpecific(ListView.java:1349)
at android.widget.ListView.layoutChildren(ListView.java:1608)
at android.widget.AbsListView.onLayout(AbsListView.java:2091)
at android.view.View.layout(View.java:14817)
at android.view.ViewGroup.layout(ViewGroup.java:4631)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1055)
at android.view.View.layout(View.java:14817)
at android.view.ViewGroup.layout(ViewGroup.java:4631)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
at android.view.View.layout(View.java:14817)
at android.view.ViewGroup.layout(ViewGroup.java:4631)
at com.android.internal.widget.ActionBarOverlayLayout.onLayout(
ActionBarOverlayLayout.java:374)
at android.view.View.layout(View.java:14817)
at android.view.ViewGroup.layout(ViewGroup.java:4631)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
at android.view.View.layout(View.java:14817)
at android.view.ViewGroup.layout(ViewGroup.java:4631)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1987)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1744)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5670)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
at android.view.Choreographer.doCallbacks(Choreographer.java:574)
at android.view.Choreographer.doFrame(Choreographer.java:544)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
活动\u main.xml
<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.multilevellist.MainActivity">
<ExpandableListView
android:id="@+id/TopLevelList"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:background="#caa551"
android:choiceMode="singleChoice"
android:groupIndicator="@null"
android:scrollbars="vertical"></ExpandableListView>
<com.multilevellist.MainActivity.NextLevelListView
android:id="@+id/NextLevelList"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:background="#41ca7e"
android:choiceMode="singleChoice"
android:groupIndicator="@null"
android:scrollbars="vertical"></com.multilevellist.MainActivity.NextLevelListView>
</RelativeLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.newShop.MainActivity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="0dp"
android:id="@+id/all_levels_text">
<TextView
android:id="@+id/TextItem"
android:textColor="#000000"
android:textSize="15sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
在XML中使用
com.multilevellist.MainActivity$NextLevelListView
而不是com.multilevellist.MainActivity.NextLevelListView
。XML使用Java反射查找类。在Java反射中,$
将嵌套类与它们的父类区分开来。试试@Luksprog和laalto,谢谢你的想法,他们让我想到了dicover Android Studio不处理$符号。我已经将嵌套类NextLevelListView移到了它自己的位置。这似乎解决了眼前的问题,但突出了一个新问题。我已经编辑了这个问题,包括了新的代码和logcat。
package com.multilevellist;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnGroupExpandListener;
import android.widget.TextView;
import java.util.ArrayList;
import static android.util.Log.*;
public class MainActivity extends Activity {
private final ArrayList<Integer> groupsForEachLevel = new ArrayList<Integer>();
private static final ArrayList<Integer> minimumHeights = new ArrayList<Integer>();
private final ArrayList<Object> allLevelViews = new ArrayList<Object>();
public class ExpandChecker implements OnGroupExpandListener {
private ExpandableListView listView;
private int level;
public ExpandChecker(ExpandableListView listView, int level) {
w("*****", "onGroupExpand constructor level " + level);
this.listView = listView;
this.level = level;
}
@Override
public void onGroupExpand(int groupPosition) {
w("*****", "onGroupExpand " + level + " " + minimumHeights.toString());
for (int i = 0; i < groupsForEachLevel.get(level); i++) {
if (i != groupPosition && listView.isGroupExpanded(i)) {
listView.collapseGroup(i);
for (int ii = level + 1; ii < minimumHeights.size(); ii++) {
minimumHeights.set(ii, 0);
}
}
}
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
groupsForEachLevel.add(5);
groupsForEachLevel.add(5);
groupsForEachLevel.add(5);
groupsForEachLevel.add(5);
groupsForEachLevel.add(5);
groupsForEachLevel.add(5);
groupsForEachLevel.add(5);
minimumHeights.ensureCapacity(groupsForEachLevel.size());
allLevelViews.ensureCapacity(groupsForEachLevel.size());
for (int i = 0; i < groupsForEachLevel.size(); i++) {
minimumHeights.add(0);
allLevelViews.add(null);
}
minimumHeights.set(0, 1500);
setContentView(R.layout.activity_main);
ExpandableListView topLevelListView =
(ExpandableListView) findViewById(R.id.TopLevelList);
CustomListAdapter customListAdapter = new CustomListAdapter(0);
topLevelListView.setOnGroupExpandListener(new ExpandChecker(topLevelListView, 0));
topLevelListView.setAdapter(customListAdapter);
minimumHeights.set(0, topLevelListView.getHeight());
allLevelViews.set(0, topLevelListView);
}
public class CustomListAdapter extends BaseExpandableListAdapter {
private NextLevelListView nextLevelListView;
private final int level;
private final int lastLevel;
private int overAllHeight;
private final int groupsInThisLevel;
private final int childCount;
public CustomListAdapter(int level) {
super();
this.level = level;
this.groupsInThisLevel = groupsForEachLevel.get(level);
this.childCount = 1;
lastLevel = groupsForEachLevel.size();
}
@Override
public Object getChild(int groupPosition, int childPosition) {
w("*****", "getChild");
return nextLevelListView;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
w("*****", "getChildId");
return childPosition;
}
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
w("*****", "onChildView - parent class=" + parent.getClass().getName());
int nextLevel = this.level + 1;
Log.w("****", "getChildView level=" + level);
if (nextLevel <= lastLevel) {
Log.w("****", "getChildView 1 nextLevel=" + nextLevel);
CustomListAdapter customListAdapter = new CustomListAdapter(nextLevel);
Log.w("****", "getChildView 2 nextLevel=" + nextLevel);
nextLevelListView = (NextLevelListView) findViewById(R.id.NextLevelList);
Log.w("****", "getChildView 3 nextLevel=" + nextLevel);
nextLevelListView.setLevel(nextLevel);
nextLevelListView.setGroupIndicator(null);
nextLevelListView.setOnGroupExpandListener(new
ExpandChecker(nextLevelListView, nextLevel));
nextLevelListView.setAdapter(customListAdapter);
Log.w("****", "getChildView 4 nextLevel=" + nextLevel);
return nextLevelListView;
}
return null;
}
@Override
public int getChildrenCount(int groupPosition) {
w("*****", "getChildrenCount " + childCount);
return childCount;
}
@Override
public Object getGroup(int groupPosition) {
w("*****", "getGroup");
return groupPosition;
}
@Override
public int getGroupCount() {
w("*****", "getGroupCount " + groupsInThisLevel);
return this.groupsInThisLevel;
}
@Override
public long getGroupId(int groupPosition) {
w("*****", "getGroupId " + groupPosition);
return groupPosition;
}
@Override
public View getGroupView(final int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
Log.w("****", "getCGroupView 1 level=" + level);
if (convertView == null) {
LayoutInflater layoutInflater = MainActivity.this.getLayoutInflater();
convertView = layoutInflater.inflate(R.layout.all_levels_text, null);
}
Log.w("****", "getCGroupView 2 level=" + level);
TextView item = (TextView) convertView.findViewById(R.id.TextItem);
if (level == 0) {
item.setBackgroundColor(Color.CYAN);
} else if (level == groupsForEachLevel.size() - 1) {
item.setBackgroundColor(Color.GREEN);
} else {
item.setBackgroundColor(Color.LTGRAY);
}
item.setText(Integer.toString(level) + " -- " + Integer.toString(groupPosition));
item.setPadding(30 * (level + 1), 0, 0, 0);
if (level == (groupsForEachLevel.size() - 1)) {
convertView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
w("****", "in click listener - future action not yet set ");
}
});
}
if (groupPosition == (groupsInThisLevel - 1)
&& parent.getHeight() != 0
&& minimumHeights.get(level) == 0) {
for (int i = level; i >= 0; i--) {
minimumHeights.set(i, minimumHeights.get(i) + parent.getMeasuredHeight());
}
allLevelViews.set(level, parent);
Log.w("****", "add to array parent l=" +
level +
" type=" +
allLevelViews.get(level).getClass().getName() +
" " +
minimumHeights.toString() +
" " +
((ExpandableListView) allLevelViews.get(level)).getHeight());
}
return convertView;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
}
package com.multilevellist;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ExpandableListView;
import static android.util.Log.w;
public class NextLevelListView extends ExpandableListView {
private int level = 0;
public NextLevelListView(Context context ) {
super(context );
}
public NextLevelListView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
}
@Override
public void onMeasure(int width, int height) {
w("*****", "onMeasure 1 ");
height = MeasureSpec.makeMeasureSpec(1500, MeasureSpec.AT_MOST);
w("*****", "onMeasure 2 ");
super.onMeasure(width, height);
w("*****", "onMeasure 3 ");
}
public void setLevel(int level) {
this.level = level;
}
}