求指教:练习viewSwitcher时出错,找了半天不知道哪里出错了

时间:2022-06-14 13:07:25
就是用一个GridView设置一个ViewSwitcher,用动态的BaseAdapter提供数据给GrideView,仿安卓系统界面
代码看起来有点多但是实现的东西很简单,找不出错因,望大牛给予指导
MainActivity.java:
public class MainActivity extends Activity {

    public static final int NUM_PER_SCREEN = 12 ; //每屏显示3*4个元素
    public static class DataItem{      //每个元素含一个name和一个drawable
     public String dataName;
     public Drawable drawable;
    }
   
    private ArrayList<DataItem> items = new ArrayList<DataItem>();
    private int screenNum = -1;  //当前屏幕编号(从0开始),-1代表还未生成屏幕
    private int screenCount;  //屏幕总数
   
    ViewSwitcher viewSwitcher;
    LayoutInflater inflater;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        inflater = LayoutInflater.from(MainActivity.this);
        
        for(int i = 0 ; i < 40 ; i++){                  //填充ArrayList<DataItem>,共40个元素
         DataItem item = new DataItem();
         item.dataName = "" + i+1;
         item.drawable = getResources().getDrawable(R.drawable.ic_launcher);
         items.add(item);
        }
        
        screenCount = items.size() % NUM_PER_SCREEN == 0 ? items.size() / NUM_PER_SCREEN : items.size() / NUM_PER_SCREEN +1;
        viewSwitcher = (ViewSwitcher) findViewById(R.id.viewSwither);
        
        ViewFactory factory = new ViewFactory(){
         @Override
         public View makeView(){
         return inflater.inflate(R.layout.slidelistview, null);  //加载Gridview
         }
        };
        
        viewSwitcher.setFactory(factory);
        next(null);    //显示第一屏
    }
   
    public void next (View v){
     screenNum++;
     viewSwitcher.setInAnimation(this,R.anim.slide_in_right);      //应该不是动画的问题,就不贴代码了
     viewSwitcher.setOutAnimation(this,R.anim.slide_out_left);
     ( (GridView) viewSwitcher.getNextView() ).setAdapter(adapter);    //加载动态的adapter
     viewSwitcher.showNext();
    }
    public void pre (View v){
     screenNum--;
     viewSwitcher.setInAnimation(this,R.anim.slide_in_left);
     viewSwitcher.setOutAnimation(this,R.anim.slide_out_right);
     ( (GridView) viewSwitcher.getNextView() ).setAdapter(adapter);
     viewSwitcher.showPrevious();
    }
    
    private BaseAdapter adapter = new BaseAdapter() {               //动态Adapter

@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View view = convertView ;
if(convertView == null){
view = inflater.inflate(R.layout.lableicon, null);  //  元素是name和drawable的线性布局lableicon
}

ImageView imageView = (ImageView) findViewById(R.id.imageView);
TextView textView = (TextView) findViewById(R.id.textView); 
imageView.setImageDrawable(getItem(position).drawable);
textView.setText(getItem(position).dataName);

return view;
}

@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}

@Override
public DataItem getItem(int position) {
// TODO Auto-generated method stub
return items.get(screenNum * NUM_PER_SCREEN + position);

}

@Override
public int getCount() {
// TODO Auto-generated method stub
if(screenNum == screenCount-1 && items.size() % NUM_PER_SCREEN != 0 )
return items.size() % NUM_PER_SCREEN ;
return NUM_PER_SCREEN; 
}
};
}



12-26 14:54:45.183: W/dalvikvm(615): threadid=1: thread exiting with uncaught exception (group=0x40a13300)

12-26 14:54:45.214: E/AndroidRuntime(615): FATAL EXCEPTION: main
12-26 14:54:45.214: E/AndroidRuntime(615): java.lang.NullPointerException
12-26 14:54:45.214: E/AndroidRuntime(615):  at com.learning.viewswitchertest.MainActivity$1.getView(MainActivity.java:97)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.widget.AbsListView.obtainView(AbsListView.java:2271)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.widget.GridView.onMeasure(GridView.java:1030)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.view.View.measure(View.java:15172)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4816)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.view.View.measure(View.java:15172)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:617)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:399)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.view.View.measure(View.java:15172)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4816)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.view.View.measure(View.java:15172)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.widget.LinearLayout.measureVertical(LinearLayout.java:833)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.widget.LinearLayout.onMeasure(LinearLayout.java:574)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.view.View.measure(View.java:15172)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4816)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
12-26 14:54:45.214: E/AndroidRuntime(615):  at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2148)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.view.View.measure(View.java:15172)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1850)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1102)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1275)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4214)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.view.Choreographer.doCallbacks(Choreographer.java:555)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.view.Choreographer.doFrame(Choreographer.java:525)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.os.Handler.handleCallback(Handler.java:615)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.os.Handler.dispatchMessage(Handler.java:92)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.os.Looper.loop(Looper.java:137)
12-26 14:54:45.214: E/AndroidRuntime(615):  at android.app.ActivityThread.main(ActivityThread.java:4745)
12-26 14:54:45.214: E/AndroidRuntime(615):  at java.lang.reflect.Method.invokeNative(Native Method)
12-26 14:54:45.214: E/AndroidRuntime(615):  at java.lang.reflect.Method.invoke(Method.java:511)
12-26 14:54:45.214: E/AndroidRuntime(615):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
12-26 14:54:45.214: E/AndroidRuntime(615):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
12-26 14:54:45.214: E/AndroidRuntime(615):  at dalvik.system.NativeStart.main(Native Method)

12-26 14:58:13.533: I/Process(615): Sending signal. PID: 615 SIG: 9

9 个解决方案

#1


R.layout.activity_main:
<?xml version="1.0" encoding="utf-8"?>
<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"
     >

    <ViewSwitcher
        android:id="@+id/viewSwither"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        />
    
    <Button
        android:id="@+id/button_pre"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="prev"
        android:text="@string/pre"
        />

    <Button
        android:id="@+id/button_next"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="next"
        android:text="@string/next"
        />

</RelativeLayout>

R.layout.slidelistview
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/gridView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:verticalSpacing="5dp"
    android:gravity="center" 
    android:stretchMode="spacingWidth"
    android:numColumns="4">
  

</GridView>

R.layout.lableicon.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center" >
    
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />"
    </LinearLayout>

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.learning.viewswitchertest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="20" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

#2


不是报了NullPointer 控制真错误吗?应该是你有变量没有初始化就直接用了,你点Logcat中的日志,跳转到错误位置就知道了

12-26 14:54:45.214: E/AndroidRuntime(615): FATAL EXCEPTION: main
12-26 14:54:45.214: E/AndroidRuntime(615): java.lang.NullPointerException
12-26 14:54:45.214: E/AndroidRuntime(615):  at com.learning.viewswitchertest.MainActivity$1.getView(MainActivity.java:97)

#3


应该是这里错了:
 private BaseAdapter adapter = new BaseAdapter() {               //动态Adapter
         
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
            View view = convertView ;
            if(convertView == null){
                view = inflater.inflate(R.layout.lableicon, null);  //  元素是name和drawable的线性布局lableicon
            }
             
            ImageView imageView = (ImageView) view .findViewById(R.id.imageView);
            TextView textView = (TextView) view .findViewById(R.id.textView);
 
            imageView.setImageDrawable(getItem(position).drawable);
            textView.setText(getItem(position).dataName);
             
            return view;
        }
         
        @Override
        public long getItemId(int position) {
            // TODO Auto-generated method stub
            return position;
        }
         
        @Override
        public DataItem getItem(int position) {
            // TODO Auto-generated method stub
        return items.get(screenNum * NUM_PER_SCREEN + position);
 
        }
         
        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            if(screenNum == screenCount-1 && items.size() % NUM_PER_SCREEN != 0 )
                return items.size() % NUM_PER_SCREEN ;
            return NUM_PER_SCREEN; 
        }
    };
}

#4


引用 2 楼 WantD 的回复:
不是报了NullPointer 控制真错误吗?应该是你有变量没有初始化就直接用了,你点Logcat中的日志,跳转到错误位置就知道了

12-26 14:54:45.214: E/AndroidRuntime(615): FATAL EXCEPTION: main
12-26 14:54:45.214: E/AndroidRuntime(615): java.lang.NullPointerException
12-26 14:54:45.214: E/AndroidRuntime(615):  at com.learning.viewswitchertest.MainActivity$1.getView(MainActivity.java:97)


定位到 原代码的97行: imageView.setImageDrawable(getItem(position).drawable);
其中drawable在 现在的第23行 for循环中已经初始化了,还是找不到错

#5


引用 3 楼 WantD 的回复:
应该是这里错了:
 private BaseAdapter adapter = new BaseAdapter() {               //动态Adapter
         
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
            View view = convertView ;
            if(convertView == null){
                view = inflater.inflate(R.layout.lableicon, null);  //  元素是name和drawable的线性布局lableicon
            }
             
            ImageView imageView = (ImageView) view .findViewById(R.id.imageView);
            TextView textView = (TextView) view .findViewById(R.id.textView);
 
            imageView.setImageDrawable(getItem(position).drawable);
            textView.setText(getItem(position).dataName);
             
            return view;
        }
         
        @Override
        public long getItemId(int position) {
            // TODO Auto-generated method stub
            return position;
        }
         
        @Override
        public DataItem getItem(int position) {
            // TODO Auto-generated method stub
        return items.get(screenNum * NUM_PER_SCREEN + position);
 
        }
         
        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            if(screenNum == screenCount-1 && items.size() % NUM_PER_SCREEN != 0 )
                return items.size() % NUM_PER_SCREEN ;
            return NUM_PER_SCREEN; 
        }
    };
}


能详细点么

#6


把我代码的红色部分替换你原来的代码不就行了吗

#7


引用 6 楼 WantD 的回复:
把我代码的红色部分替换你原来的代码不就行了吗

不好意思啊,之前看得太快没看出你加的View
现在程序可以跑起来了但是gridView没有加载出图标,界面只有两个button,怀疑adapter中有问题,能帮我看看么谢谢

#8


引用 7 楼 Rachel_McAdams 的回复:
Quote: 引用 6 楼 WantD 的回复:

把我代码的红色部分替换你原来的代码不就行了吗

不好意思啊,之前看得太快没看出你加的View
现在程序可以跑起来了但是gridView没有加载出图标,界面只有两个button,怀疑adapter中有问题,能帮我看看么谢谢

也没有报错

#9


没加载出图标你要确认你你的imageview是否有设置成功,跟日志看看。需要具体调试才知道是什么问题

#1


R.layout.activity_main:
<?xml version="1.0" encoding="utf-8"?>
<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"
     >

    <ViewSwitcher
        android:id="@+id/viewSwither"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        />
    
    <Button
        android:id="@+id/button_pre"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="prev"
        android:text="@string/pre"
        />

    <Button
        android:id="@+id/button_next"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="next"
        android:text="@string/next"
        />

</RelativeLayout>

R.layout.slidelistview
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/gridView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:verticalSpacing="5dp"
    android:gravity="center" 
    android:stretchMode="spacingWidth"
    android:numColumns="4">
  

</GridView>

R.layout.lableicon.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center" >
    
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />"
    </LinearLayout>

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.learning.viewswitchertest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="20" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

#2


不是报了NullPointer 控制真错误吗?应该是你有变量没有初始化就直接用了,你点Logcat中的日志,跳转到错误位置就知道了

12-26 14:54:45.214: E/AndroidRuntime(615): FATAL EXCEPTION: main
12-26 14:54:45.214: E/AndroidRuntime(615): java.lang.NullPointerException
12-26 14:54:45.214: E/AndroidRuntime(615):  at com.learning.viewswitchertest.MainActivity$1.getView(MainActivity.java:97)

#3


应该是这里错了:
 private BaseAdapter adapter = new BaseAdapter() {               //动态Adapter
         
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
            View view = convertView ;
            if(convertView == null){
                view = inflater.inflate(R.layout.lableicon, null);  //  元素是name和drawable的线性布局lableicon
            }
             
            ImageView imageView = (ImageView) view .findViewById(R.id.imageView);
            TextView textView = (TextView) view .findViewById(R.id.textView);
 
            imageView.setImageDrawable(getItem(position).drawable);
            textView.setText(getItem(position).dataName);
             
            return view;
        }
         
        @Override
        public long getItemId(int position) {
            // TODO Auto-generated method stub
            return position;
        }
         
        @Override
        public DataItem getItem(int position) {
            // TODO Auto-generated method stub
        return items.get(screenNum * NUM_PER_SCREEN + position);
 
        }
         
        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            if(screenNum == screenCount-1 && items.size() % NUM_PER_SCREEN != 0 )
                return items.size() % NUM_PER_SCREEN ;
            return NUM_PER_SCREEN; 
        }
    };
}

#4


引用 2 楼 WantD 的回复:
不是报了NullPointer 控制真错误吗?应该是你有变量没有初始化就直接用了,你点Logcat中的日志,跳转到错误位置就知道了

12-26 14:54:45.214: E/AndroidRuntime(615): FATAL EXCEPTION: main
12-26 14:54:45.214: E/AndroidRuntime(615): java.lang.NullPointerException
12-26 14:54:45.214: E/AndroidRuntime(615):  at com.learning.viewswitchertest.MainActivity$1.getView(MainActivity.java:97)


定位到 原代码的97行: imageView.setImageDrawable(getItem(position).drawable);
其中drawable在 现在的第23行 for循环中已经初始化了,还是找不到错

#5


引用 3 楼 WantD 的回复:
应该是这里错了:
 private BaseAdapter adapter = new BaseAdapter() {               //动态Adapter
         
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
            View view = convertView ;
            if(convertView == null){
                view = inflater.inflate(R.layout.lableicon, null);  //  元素是name和drawable的线性布局lableicon
            }
             
            ImageView imageView = (ImageView) view .findViewById(R.id.imageView);
            TextView textView = (TextView) view .findViewById(R.id.textView);
 
            imageView.setImageDrawable(getItem(position).drawable);
            textView.setText(getItem(position).dataName);
             
            return view;
        }
         
        @Override
        public long getItemId(int position) {
            // TODO Auto-generated method stub
            return position;
        }
         
        @Override
        public DataItem getItem(int position) {
            // TODO Auto-generated method stub
        return items.get(screenNum * NUM_PER_SCREEN + position);
 
        }
         
        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            if(screenNum == screenCount-1 && items.size() % NUM_PER_SCREEN != 0 )
                return items.size() % NUM_PER_SCREEN ;
            return NUM_PER_SCREEN; 
        }
    };
}


能详细点么

#6


把我代码的红色部分替换你原来的代码不就行了吗

#7


引用 6 楼 WantD 的回复:
把我代码的红色部分替换你原来的代码不就行了吗

不好意思啊,之前看得太快没看出你加的View
现在程序可以跑起来了但是gridView没有加载出图标,界面只有两个button,怀疑adapter中有问题,能帮我看看么谢谢

#8


引用 7 楼 Rachel_McAdams 的回复:
Quote: 引用 6 楼 WantD 的回复:

把我代码的红色部分替换你原来的代码不就行了吗

不好意思啊,之前看得太快没看出你加的View
现在程序可以跑起来了但是gridView没有加载出图标,界面只有两个button,怀疑adapter中有问题,能帮我看看么谢谢

也没有报错

#9


没加载出图标你要确认你你的imageview是否有设置成功,跟日志看看。需要具体调试才知道是什么问题