根据方向变化,android 中的灵活模块 UI

Flexible Modular UI in android as per Orientation Change

我正在制作的应用程序在纵向模式下显示 fragmentA(包含 Listview),在横向模式下显示 fragmentA 和 fragmentB(Listview 及其相应的描述)。它一直在崩溃,我的直觉说要么有一个MainActivity 中的 if-else 条件错误或通信中出现问题 pattern.I 请求大家帮忙。这是我的 MainActivity.xml

package com.example.prince.fragment_modularui2;

import android.content.Intent;
import android.content.res.Resources;

import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity implements FragmentA.Communicator{
    String s;
    Resources r=getResources();
    String[] a=r.getStringArray(R.array.descr);



    FragmentA fa;
    FragmentB fb;
    FragmentManager manager;


    @Override
    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        manager=getSupportFragmentManager();
        //fa always present
        fa= (FragmentA) manager.findFragmentById(R.id.fragment);
        fb= (FragmentB) manager.findFragmentById(R.id.fragment2);
        fa.setCommunicator(this);
    }

    @Override
    public void respond(int data) {

            Intent i=new Intent(this,AnotherActivity.class);
            i.putExtra("index",data);
            startActivity(i);



    }
}

这里是 activity_main.xml 肖像

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">


    <fragment
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.example.prince.fragment_modularui2.FragmentA"
        android:id="@+id/fragment"
        ></fragment>


</LinearLayout>

activity_main 横向

<?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">

    <fragment
        android:id="@+id/fragment"
        android:name="com.example.prince.fragment_modularui2.FragmentA"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true" />

    <fragment
        android:id="@+id/fragment2"
        android:name="com.example.prince.fragment_modularui2.FragmentB"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentTop="true" />
</LinearLayout>

其余代码为https://github.com/AlmightyHeathcliff/Fragment_ModularUi2

stackTrace 是

07-18 09:45:09.252 1974-1974/? D/AndroidRuntime: >>>>>> START com.android.internal.os.RuntimeInit uid 0 <<<<<<
07-18 09:45:09.254 1974-1974/? D/AndroidRuntime: CheckJNI is OFF
07-18 09:45:09.289 1974-1974/? W/art: Unexpected CPU variant for X86 using defaults: x86
07-18 09:45:09.301 1974-1974/? D/ICU: No timezone override file found: /data/misc/zoneinfo/current/icu/icu_tzdata.dat
07-18 09:45:09.316 1974-1974/? E/memtrack: Couldn't load memtrack module (No such file or directory)
07-18 09:45:09.316 1974-1974/? E/android.os.Debug: failed to load memtrack module: -2
07-18 09:45:09.317 1974-1974/? I/Radio-JNI: register_android_hardware_Radio DONE
07-18 09:45:09.325 1974-1974/? D/AndroidRuntime: Calling main entry com.android.commands.pm.Pm
07-18 09:45:09.330 1974-1974/? I/art: System.exit called, status: 0
07-18 09:45:09.330 1974-1974/? I/AndroidRuntime: VM exiting with result code 0.
07-18 09:45:09.333 1974-1982/? W/MessageQueue: Handler (android.os.Handler) {f6bbfb3} sending message to a Handler on a dead thread
                                               java.lang.IllegalStateException: Handler (android.os.Handler) {f6bbfb3} sending message to a Handler on a dead thread
                                                   at android.os.MessageQueue.enqueueMessage(MessageQueue.java:543)
                                                   at android.os.Handler.enqueueMessage(Handler.java:643)
                                                   at android.os.Handler.sendMessageAtTime(Handler.java:612)
                                                   at android.os.Handler.sendMessageDelayed(Handler.java:582)
                                                   at android.os.Handler.post(Handler.java:338)
                                                   at android.os.ResultReceiver$MyResultReceiver.send(ResultReceiver.java:57)
                                                   at com.android.internal.os.IResultReceiver$Stub.onTransact(IResultReceiver.java:58)
                                                   at android.os.Binder.execTransact(Binder.java:565)
07-18 09:45:09.972 1993-1993/? D/AndroidRuntime: >>>>>> START com.android.internal.os.RuntimeInit uid 0 <<<<<<
07-18 09:45:09.976 1993-1993/? D/AndroidRuntime: CheckJNI is OFF
07-18 09:45:10.012 1993-1993/? W/art: Unexpected CPU variant for X86 using defaults: x86
07-18 09:45:10.015 1993-1993/? D/ICU: No timezone override file found: /data/misc/zoneinfo/current/icu/icu_tzdata.dat
07-18 09:45:10.049 1993-1993/? E/memtrack: Couldn't load memtrack module (No such file or directory)
07-18 09:45:10.049 1993-1993/? E/android.os.Debug: failed to load memtrack module: -2
07-18 09:45:10.050 1993-1993/? I/Radio-JNI: register_android_hardware_Radio DONE
07-18 09:45:10.059 1993-1993/? D/AndroidRuntime: Calling main entry com.android.commands.pm.Pm
07-18 09:45:10.064 1993-2001/? W/MessageQueue: Handler (android.os.Handler) {f6bbfb3} sending message to a Handler on a dead thread
                                               java.lang.IllegalStateException: Handler (android.os.Handler) {f6bbfb3} sending message to a Handler on a dead thread
                                                   at android.os.MessageQueue.enqueueMessage(MessageQueue.java:543)
                                                   at android.os.Handler.enqueueMessage(Handler.java:643)
                                                   at android.os.Handler.sendMessageAtTime(Handler.java:612)
                                                   at android.os.Handler.sendMessageDelayed(Handler.java:582)
                                                   at android.os.Handler.post(Handler.java:338)
                                                   at android.os.ResultReceiver$MyResultReceiver.send(ResultReceiver.java:57)
                                                   at com.android.internal.os.IResultReceiver$Stub.onTransact(IResultReceiver.java:58)
                                                   at android.os.Binder.execTransact(Binder.java:565)
07-18 09:45:10.064 1993-1993/? I/art: System.exit called, status: 0
07-18 09:45:10.064 1993-1993/? I/AndroidRuntime: VM exiting with result code 0.
07-18 09:45:13.487 2005-2005/? D/AndroidRuntime: >>>>>> START com.android.internal.os.RuntimeInit uid 0 <<<<<<
07-18 09:45:13.491 2005-2005/? D/AndroidRuntime: CheckJNI is OFF
07-18 09:45:13.569 2005-2005/? W/art: Unexpected CPU variant for X86 using defaults: x86
07-18 09:45:13.575 2005-2005/? D/ICU: No timezone override file found: /data/misc/zoneinfo/current/icu/icu_tzdata.dat
07-18 09:45:13.708 2009-2009/? D/AndroidRuntime: >>>>>> START com.android.internal.os.RuntimeInit uid 0 <<<<<<
07-18 09:45:13.715 2009-2009/? D/AndroidRuntime: CheckJNI is OFF
07-18 09:45:13.760 2005-2005/? E/memtrack: Couldn't load memtrack module (No such file or directory)
07-18 09:45:13.760 2005-2005/? E/android.os.Debug: failed to load memtrack module: -2
07-18 09:45:13.761 2005-2005/? I/Radio-JNI: register_android_hardware_Radio DONE
07-18 09:45:13.776 2005-2005/? D/AndroidRuntime: Calling main entry com.android.commands.wm.Wm
07-18 09:45:13.814 2009-2009/? W/art: Unexpected CPU variant for X86 using defaults: x86
07-18 09:45:13.825 2009-2009/? D/ICU: No timezone override file found: /data/misc/zoneinfo/current/icu/icu_tzdata.dat
07-18 09:45:13.833 2005-2005/? D/AndroidRuntime: Shutting down VM
07-18 09:45:13.839 2005-2019/? W/art: Thread attaching while runtime is shutting down: Binder:2005_2
07-18 09:45:13.839 2005-2019/? I/AndroidRuntime: NOTE: attach of thread 'Binder:2005_2' failed
07-18 09:45:13.891 2009-2009/? E/memtrack: Couldn't load memtrack module (No such file or directory)
07-18 09:45:13.891 2009-2009/? E/android.os.Debug: failed to load memtrack module: -2
07-18 09:45:13.892 2009-2009/? I/Radio-JNI: register_android_hardware_Radio DONE
07-18 09:45:13.903 2009-2009/? D/AndroidRuntime: Calling main entry com.android.commands.am.Am
07-18 09:45:13.909 765-1149/system_process I/ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.example.prince.fragment_modularui2/.MainActivity} from uid 0 on display 0
07-18 09:45:13.919 2009-2009/? D/AndroidRuntime: Shutting down VM
07-18 09:45:13.993 765-1021/system_process W/ActivityManager: Slow operation: 75ms so far, now at startProcess: returned from zygote!
07-18 09:45:13.993 765-1021/system_process W/ActivityManager: Slow operation: 75ms so far, now at startProcess: done updating battery stats
07-18 09:45:13.993 765-1021/system_process W/ActivityManager: Slow operation: 75ms so far, now at startProcess: building log message
07-18 09:45:13.993 765-1021/system_process I/ActivityManager: Start proc 2027:com.example.prince.fragment_modularui2/u0a115 for activity com.example.prince.fragment_modularui2/.MainActivity
07-18 09:45:13.993 765-1021/system_process W/ActivityManager: Slow operation: 75ms so far, now at startProcess: starting to update pids map
07-18 09:45:13.993 765-1021/system_process W/ActivityManager: Slow operation: 75ms so far, now at startProcess: done updating pids map
07-18 09:45:13.993 765-1021/system_process W/ActivityManager: Slow operation: 75ms so far, now at startProcess: done starting proc!
07-18 09:45:14.003 2027-2027/? I/art: Late-enabling -Xcheck:jni
07-18 09:45:14.004 2027-2027/? W/art: Unexpected CPU variant for X86 using defaults: x86
07-18 09:45:14.258 500-757/? D/gralloc_vbox86: gralloc_alloc: format 1 and usage 0x933 imply creation of host color buffer
07-18 09:45:14.784 2027-2027/com.example.prince.fragment_modularui2 W/System: ClassLoader referenced unknown path: /data/app/com.example.prince.fragment_modularui2-1/lib/x86
07-18 09:45:14.813 2027-2027/com.example.prince.fragment_modularui2 I/InstantRun: starting instant run server: is main process
07-18 09:45:14.814 2027-2027/com.example.prince.fragment_modularui2 V/InstantRun: Starting server socket listening for package com.example.prince.fragment_modularui2 on android.net.LocalSocketAddress@8989009
07-18 09:45:14.814 2027-2027/com.example.prince.fragment_modularui2 V/InstantRun: Started server for package com.example.prince.fragment_modularui2
07-18 09:45:14.903 2027-2027/com.example.prince.fragment_modularui2 D/AndroidRuntime: Shutting down VM
07-18 09:45:14.904 2027-2027/com.example.prince.fragment_modularui2 E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                      Process: com.example.prince.fragment_modularui2, PID: 2027
                                                                                      java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.prince.fragment_modularui2/com.example.prince.fragment_modularui2.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
                                                                                          at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2567)
                                                                                          at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
                                                                                          at android.app.ActivityThread.-wrap12(ActivityThread.java)
                                                                                          at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
                                                                                          at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                          at android.os.Looper.loop(Looper.java:154)
                                                                                          at android.app.ActivityThread.main(ActivityThread.java:6119)
                                                                                          at java.lang.reflect.Method.invoke(Native Method)
                                                                                          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
                                                                                          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
                                                                                       Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
                                                                                          at android.content.ContextWrapper.getResources(ContextWrapper.java:86)
                                                                                          at android.view.ContextThemeWrapper.getResourcesInternal(ContextThemeWrapper.java:127)
                                                                                          at android.view.ContextThemeWrapper.getResources(ContextThemeWrapper.java:121)
                                                                                          at android.support.v7.app.AppCompatActivity.getResources(AppCompatActivity.java:549)
                                                                                          at com.example.prince.fragment_modularui2.MainActivity.<init>(MainActivity.java:12)
                                                                                          at java.lang.Class.newInstance(Native Method)
                                                                                          at android.app.Instrumentation.newActivity(Instrumentation.java:1078)
                                                                                          at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2557)
                                                                                          at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) 
                                                                                          at android.app.ActivityThread.-wrap12(ActivityThread.java) 
                                                                                          at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) 
                                                                                          at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                                          at android.os.Looper.loop(Looper.java:154) 
                                                                                          at android.app.ActivityThread.main(ActivityThread.java:6119) 
                                                                                          at java.lang.reflect.Method.invoke(Native Method) 
                                                                                          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
                                                                                          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 
07-18 09:45:14.907 765-1021/system_process W/ActivityManager:   Force finishing activity com.example.prince.fragment_modularui2/.MainActivity
07-18 09:45:15.031 500-505/? D/gralloc_vbox86: gralloc_alloc: format 1 and usage 0x900 imply creation of host color buffer
07-18 09:45:15.058 500-505/? D/gralloc_vbox86: gralloc_alloc: format 1 and usage 0x900 imply creation of host color buffer
07-18 09:45:15.115 500-505/? D/gralloc_vbox86: gralloc_alloc: format 1 and usage 0x900 imply creation of host color buffer
07-18 09:45:15.232 765-1842/system_process I/OpenGLRenderer: Initialized EGL, version 1.4
07-18 09:45:15.232 765-1842/system_process D/OpenGLRenderer: Swap behavior 1
07-18 09:45:15.429 765-779/system_process W/ActivityManager: Activity pause timeout for ActivityRecord{b0310c2 u0 com.example.prince.fragment_modularui2/.MainActivity t693 f}
07-18 09:45:15.431 765-779/system_process I/ActivityManager: Killing 1353:android.process.media/u0a10 (adj 906): empty #17
07-18 09:45:15.432 765-779/system_process I/WindowManager: Failed to capture screenshot of Token{7756ed3 ActivityRecord{b0310c2 u0 com.example.prince.fragment_modularui2/.MainActivity t693 f}} appWin=Window{7f1e54b u0 Starting com.example.prince.fragment_modularui2} drawState=1
07-18 09:45:15.448 765-786/system_process I/Choreographer: Skipped 70 frames!  The application may be doing too much work on its main thread.
07-18 09:45:15.452 765-1150/system_process D/ActivityManager: cleanUpApplicationRecord -- 1353
07-18 09:45:15.456 765-1842/system_process E/EGL_emulation: tid 1842: eglSurfaceAttrib(1174): error 0x3009 (EGL_BAD_MATCH)
07-18 09:45:15.456 765-1842/system_process W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xc4afa800, error=EGL_BAD_MATCH
07-18 09:45:16.337 765-780/system_process I/Choreographer: Skipped 52 frames!  The application may be doing too much work on its main thread.
07-18 09:45:25.438 765-779/system_process W/ActivityManager: Activity destroy timeout for ActivityRecord{b0310c2 u0 com.example.prince.fragment_modularui2/.MainActivity t693 f}

从堆栈跟踪中我得知您正在对一个空的 Context 调用 getResources()。这是有道理的,因为您将资源声明为如下字段:

Resources res = getResources();

这会在 activity 创建之前执行,但您只能在 activity 创建后调用 getResources()。所以解决方案是像这样声明你的资源:

private Resources res;

并且在您的 activity onCreate 方法中您执行:

res = getResources();

这也意味着在执行 onCreate 方法之前,您不能使用 res 变量。通常最好不要将资源声明为这样的变量,而是将字符串数组声明为:

String[] a;

然后在 onCreate 中调用:a = getResources().getStringArray(R.array.desc);

我可以给你的另一个提示是更清楚地命名你的变量。名为 'a' 的字符串数组描述性不强。您可以将其命名为 descriptionArray 以使其更清楚。