当改变屏幕方向时,如何在ViewFlipper中保留当前视图

4

在 ViewFlipper 中,是否有保留当前视图的好方法,同时仍然能够加载 layout-port 文件夹?也许可以使用 onRetainNonConfigurationInstance() 实现?如果是这样,我该如何实现它?我尝试了某人提供的解决方案:

android:configChanges="orientation|keyboardHidden"

在清单文件中。

问题在于Android会忽略我的layout-port文件夹,而这个文件夹可以重新排列输入字段和按钮。

--更新--

这是我添加了hooked82的代码后的代码。我添加了抛出错误的部分:

public class AtriumMain extends Activity {
    Login login = new Login();

    String username, password;
    EditText user, pass, serverName, propertyID;

    Context context;
    CharSequence text;
    int duration, settingsClicks, doneClicks;

    final int WRONG_SETTINGS_DIALOG = 0;
    final int SET_SETTINGS_DIALOG = 1;

    LayoutInflater inflater;

    View failed_login, wrong_settings, card1, card2, set_settings;
    Button loginButton, settingsButton, doneButton, checkServer, yes_button, no_button, ok_button;
    ImageView failed_login_image, wrong_settings_image, set_settings_image;
    TextView failed_login_errorText, wrong_settings_errorText, set_settings_errorText;
    Boolean correctSettings;
    ViewFlipper flipper;
    Resources res;
    Application app;
    OutputStreamWriter settings_outstream;
    InputStream settings_instream;
    Toast failed_login_errorMessage;
    Dialog wrong_settings_errorMessage, set_settings_errorMessage;
    Builder test;


    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState != null)
        {
            int flipperPosition = savedInstanceState.getInt("CARD_NUMBER");
            flipper.setDisplayedChild(flipperPosition);
        }

        setContentView(R.layout.login);

        context = getApplicationContext();
        res = getResources();
        app = ((AtriumApplication)this.getApplication());

        inflater = getLayoutInflater();
        failed_login = inflater.inflate(R.layout.failed_login, (ViewGroup) findViewById(R.id.failed_login));
        wrong_settings = inflater.inflate(R.layout.wrong_settings, (ViewGroup) findViewById(R.id.wrong_settings));
        set_settings = inflater.inflate(R.layout.set_settings, (ViewGroup) findViewById(R.id.set_settings));

        loginButton = (Button)findViewById(R.id.login);
        settingsButton = (Button)findViewById(R.id.settings);
        doneButton = (Button)findViewById(R.id.done);
        checkServer = (Button)findViewById(R.id.check_server);

        //((Button)findViewById(R.id.login)).setOnClickListener(mAddListener);

        user = (EditText)findViewById(R.id.username);
        pass = (EditText)findViewById(R.id.password);

        serverName = (EditText)findViewById(R.id.serverName);
        propertyID = (EditText)findViewById(R.id.propertyId);

        flipper=(ViewFlipper)findViewById(R.id.cards);

        failed_login_image = (ImageView) failed_login.findViewById(R.id.failed_login_image);
        failed_login_image.setImageResource(R.drawable.warning2);

        failed_login_errorText = (TextView) failed_login.findViewById(R.id.text);
        failed_login_errorText.setText(res.getString(R.string.failed_login));

        failed_login_errorMessage = new Toast(context);
        failed_login_errorMessage.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
        failed_login_errorMessage.setDuration(Toast.LENGTH_LONG);
        failed_login_errorMessage.setView(failed_login);

        loginButton.setOnClickListener(loginListener);
        settingsButton.setOnClickListener(settingsListener);
        doneButton.setOnClickListener(doneListener);
        checkServer.setOnClickListener(checkServerListener);

        settingsClicks = 0;
        doneClicks = 0;

        if ((((AtriumApplication)app).getCorrectSettings()))
        {
            doneButton.getBackground().setColorFilter(new LightingColorFilter(0xFF0000FF, 0xFF000010));
        }
        else
        {
            doneButton.getBackground().setColorFilter(new LightingColorFilter(0xFFFF1010, 0xFFAA0000));
            showDialog(SET_SETTINGS_DIALOG);
        }
    }

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState)
    {
        int position = flipper.getDisplayedChild();
        savedInstanceState.putInt("CARD_NUMBER", position);
    }

这里是出错附近的Logcat输出:

08-20 11:23:52.730: VERBOSE/WindowManager(293): Preventing status bar from hiding by policy
08-20 11:23:52.740: VERBOSE/WindowManager(293): Preventing status bar from hiding by policy
08-20 11:23:52.760: VERBOSE/WindowManager(293): Preventing status bar from hiding by policy
08-20 11:23:52.770: VERBOSE/WindowManager(293): Preventing status bar from hiding by policy
08-20 11:23:52.790: VERBOSE/WindowManager(293): Preventing status bar from hiding by policy
08-20 11:23:52.810: VERBOSE/WindowManager(293): Preventing status bar from hiding by policy
08-20 11:23:52.820: VERBOSE/WindowManager(293): Preventing status bar from hiding by policy
08-20 11:23:52.830: INFO/SurfaceFlinger(223): id=6705 Removed Starting com.szymon.atrium idx=4 Map Size=5
08-20 11:23:52.830: VERBOSE/WindowManager(293): Preventing status bar from hiding by policy
08-20 11:23:52.830: INFO/SurfaceFlinger(223): id=6705 Removed Starting com.szymon.atrium idx=-2 Map Size=5
08-20 11:23:52.840: VERBOSE/WindowManager(293): Preventing status bar from hiding by policy
08-20 11:23:52.860: VERBOSE/WindowManager(293): Preventing status bar from hiding by policy
08-20 11:23:52.870: VERBOSE/WindowManager(293): Preventing status bar from hiding by policy
08-20 11:23:52.890: VERBOSE/WindowManager(293): Preventing status bar from hiding by policy
08-20 11:23:54.010: DEBUG/HierarchicalStateMachine(293): handleMessage: E msg.what=83
08-20 11:23:54.010: DEBUG/HierarchicalStateMachine(293): processMsg: ConnectedState
08-20 11:23:54.010: DEBUG/WifiStateMachine(293): ConnectedState{ what=83 when=-4ms arg1=936 }
08-20 11:23:54.030: DEBUG/HierarchicalStateMachine(293): handleMessage: X
08-20 11:23:57.030: DEBUG/HierarchicalStateMachine(293): handleMessage: E msg.what=83
08-20 11:23:57.030: DEBUG/HierarchicalStateMachine(293): processMsg: ConnectedState
08-20 11:23:57.030: DEBUG/WifiStateMachine(293): ConnectedState{ what=83 when=-4ms arg1=936 }
08-20 11:23:57.050: DEBUG/HierarchicalStateMachine(293): handleMessage: X
08-20 11:23:57.480: DEBUG/dalvikvm(30999): GC_EXPLICIT freed 1181K, 30% free 14894K/21255K, paused 3ms+3ms
08-20 11:24:00.000: DEBUG/KeyguardUpdateMonitor(293): received broadcast android.intent.action.TIME_TICK
08-20 11:24:00.000: DEBUG/KeyguardUpdateMonitor(293): handleTimeUpdate
08-20 11:24:00.050: DEBUG/HierarchicalStateMachine(293): handleMessage: E msg.what=83
08-20 11:24:00.050: DEBUG/HierarchicalStateMachine(293): processMsg: ConnectedState
08-20 11:24:00.050: DEBUG/WifiStateMachine(293): ConnectedState{ what=83 when=-3ms arg1=936 }
08-20 11:24:00.070: DEBUG/HierarchicalStateMachine(293): handleMessage: X
08-20 11:24:01.070: INFO/OrientationDebug(293): [pwm] in MyOrientationListener.onOrientationChanged() rotation=1  mFancyRotationAnimation=0   now call mWindowManager.setRotation()
08-20 11:24:01.070: INFO/OrientationDebug(293): [wms] in setRotation() rotation=1 alwaysSendConfiguration=false animFlags=0
08-20 11:24:01.070: INFO/OrientationDebug(293): [wms] in setRotation() now call setRotationUnchecked()
08-20 11:24:01.070: INFO/OrientationDebug(293): [pwm] rotationForOrientationLw(), orientation=-1 lastRotation=2 userRotation=3
08-20 11:24:01.070: INFO/OrientationDebug(293): [pwm] useSensorForOrientationLp(), return true #2
08-20 11:24:01.070: INFO/OrientationDebug(293): [pwm] in rotationForOrientationLw(), return #13
08-20 11:24:01.070: VERBOSE/WindowOrientationListener(293): > Orientation changed!  rotation=1
08-20 11:24:01.070: VERBOSE/WindowOrientationListener(293): Result: rotation=1, confidence=[0.0, 1.0, 0.0, 0.0], timeDeltaMS=54.104
08-20 11:24:01.240: INFO/SurfaceFlinger(223): id=6709(1638) createSurface 0x14c93c for pid 0 (1280x800),2 flag=0, FreezeSurface
08-20 11:24:01.280: INFO/OrientationDebug(293): [wms] in setRotationUncheckedLocked(), Setting rotation to 1   The rotation is came from PWM.rotationForOrientationLw()
08-20 11:24:01.280: DEBUG/SurfaceFlinger(223): mCurrentState.orientation:1 mDrawingState.orientation:2
08-20 11:24:01.280: DEBUG/TvoutSystem(293): bool android::TvoutSystem::TvoutSetRotation(int)
08-20 11:24:01.280: DEBUG/TvoutSystem(293): bool android::TvoutSystem::TvoutGetCableStatus()
08-20 11:24:01.280: DEBUG/TvoutService(230): virtual bool android::TvoutService::TvoutGetCableStatus()
08-20 11:24:01.280: DEBUG/TvoutService(Java)(293): TvoutGetCableStatus() : false
08-20 11:24:01.280: INFO/WindowManager(293): Setting rotation to 1, animFlags=0
08-20 11:24:01.280: INFO/ActivityManager(293): Config changed: { scale=1.0 imsi=0/0 loc=en_US touch=3 keys=1/1/2 nav=1/2 orien=P layout=0x10000014 uiMode=0x11 seq=291 FlipFont=0}
08-20 11:24:01.290: VERBOSE/WindowManager(293): Preventing status bar from hiding by policy
08-20 11:24:01.320: VERBOSE/WindowOrientationListener(293): > Orientation changed!  rotation=1
08-20 11:24:01.320: VERBOSE/WindowOrientationListener(293): Result: rotation=1, confidence=[0.0, 1.0, 0.0, 0.0], timeDeltaMS=54.104
08-20 11:24:01.320: INFO/WindowManager(293): Putting input method here!
08-20 11:24:01.320: DEBUG/WindowManager(293):     w.mAttrs.token=ActivityRecord{41811888 com.szymon.atrium/.AtriumMain}
08-20 11:24:01.320: DEBUG/WindowManager(293):     w.mToken=AppWindowToken{427877c0  token=ActivityRecord{41811888 com.szymon.atrium/.AtriumMain}}
08-20 11:24:01.320: DEBUG/WindowManager(293):     token=AppWindowToken{427877c0 token=ActivityRecord{41811888 com.szymon.atrium/.AtriumMain}}
08-20 11:24:01.320: INFO/SurfaceFlinger(223): id=6707 Removed com.szymon.atrium/com.szymon.atrium.AtriumMain idx=2 Map Size=5
08-20 11:24:01.320: INFO/WindowManager(293): Placing input method @5
08-20 11:24:01.330: INFO/SurfaceFlinger(223): id=6707 Removed com.szymon.atrium/com.szymon.atrium.AtriumMain idx=-2 Map Size=5
08-20 11:24:01.330: ERROR/TelephonyManager(22015): Hidden constructor called more than once per process!
08-20 11:24:01.330: INFO/WindowManager(293): Placing input method @1
08-20 11:24:01.340: DEBUG/MiniModeAppsPanel(430): ACTION_CONFIGURATION_CHANGED
08-20 11:24:02.140: VERBOSE/WindowOrientationListener(293): rotation : 1   Angle: 90   tilt: 2
08-20 11:24:03.070: DEBUG/HierarchicalStateMachine(293): handleMessage: E msg.what=83
08-20 11:24:03.070: DEBUG/HierarchicalStateMachine(293): processMsg: ConnectedState
08-20 11:24:03.070: DEBUG/WifiStateMachine(293): ConnectedState{ what=83 when=-4ms arg1=936 }
08-20 11:24:03.070: DEBUG/HierarchicalStateMachine(293): handleMessage: X
08-20 11:24:03.070: WARN/WindowManager(293): Window freeze timeout expired.
08-20 11:24:03.070: WARN/WindowManager(293): Force clearing orientation change: Window{407d1208 InputMethod paused=false}
08-20 11:24:03.390: WARN/InputConnectionWrapper.ICC(439): Timed out waiting on IInputContextCallback
08-20 11:24:03.420: WARN/Resources(439): Converting to boolean: TypedValue{t=0x3/d=0x15 "true" a=-1}
08-20 11:24:03.430: WARN/Resources(439): Converting to boolean: TypedValue{t=0x3/d=0x15 "true" a=-1}
08-20 11:24:03.590: VERBOSE/WindowOrientationListener(293): rotation : 1   Angle: 90   tilt: 0
08-20 11:24:05.070: VERBOSE/WindowOrientationListener(293): rotation : 1   Angle: 90   tilt: -2
08-20 11:24:05.430: WARN/InputConnectionWrapper.ICC(439): Timed out waiting on IInputContextCallback
08-20 11:24:05.450: ERROR/TabletStatusBar(430): closing mini mode apps panel
08-20 11:24:05.490: DEBUG/dalvikvm(439): GC_FOR_ALLOC freed 1756K, 38% free 10279K/16391K, paused 27ms
08-20 11:24:06.080: DEBUG/HierarchicalStateMachine(293): handleMessage: E msg.what=83
08-20 11:24:06.080: DEBUG/HierarchicalStateMachine(293): processMsg: ConnectedState
08-20 11:24:06.080: DEBUG/WifiStateMachine(293): ConnectedState{ what=83 when=-4ms arg1=936 }
08-20 11:24:06.090: DEBUG/HierarchicalStateMachine(293): handleMessage: X
08-20 11:24:06.290: WARN/WindowManager(293): App freeze timeout expired.
08-20 11:24:06.290: WARN/WindowManager(293): Force clearing freeze: AppWindowToken{427877c0 token=ActivityRecord{41811888 com.szymon.atrium/.AtriumMain}}
08-20 11:24:06.300: INFO/SurfaceFlinger(223): id=6710(1639) createSurface for pid 0 (800x2560),-1 flag=131072, BlackSurface
08-20 11:24:06.300: INFO/SurfaceFlinger(223): id=6711(1640) createSurface for pid 0 (1600x1280),-1 flag=131072, BlackSurface
08-20 11:24:06.300: INFO/SurfaceFlinger(223): id=6712(1641) createSurface for pid 0 (800x2560),-1 flag=131072, BlackSurface
08-20 11:24:06.310: INFO/SurfaceFlinger(223): id=6713(1642) createSurface for pid 0 (1600x1280),-1 flag=131072, BlackSurface
08-20 11:24:06.370: DEBUG/dalvikvm(15392): GC_CONCURRENT freed 458K, 37% free 7282K/11399K, paused 7ms+8ms
08-20 11:24:06.370: DEBUG/dalvikvm(20484): GC_EXPLICIT freed 9K, 5% free 6215K/6531K, paused 3ms+2ms
08-20 11:24:06.560: VERBOSE/WindowOrientationListener(293): rotation : 1   Angle: 90   tilt: -3
08-20 11:24:06.740: INFO/SurfaceFlinger(223): id=6709 Removed FreezeSurface idx=9 Map Size=4
08-20 11:24:06.740: INFO/SurfaceFlinger(223): id=6710 Removed BlackSurface idx=5 Map Size=4
08-20 11:24:06.740: INFO/SurfaceFlinger(223): id=6711 Removed BlackSurface idx=5 Map Size=4
08-20 11:24:06.750: INFO/SurfaceFlinger(223): id=6712 Removed BlackSurface idx=5 Map Size=4
08-20 11:24:06.750: INFO/SurfaceFlinger(223): id=6712 Removed BlackSurface idx=-2 Map Size=4
08-20 11:24:06.750: INFO/SurfaceFlinger(223): id=6711 Removed BlackSurface idx=-2 Map Size=4
08-20 11:24:06.750: INFO/SurfaceFlinger(223): id=6710 Removed BlackSurface idx=-2 Map Size=4
08-20 11:24:06.750: INFO/SurfaceFlinger(223): id=6709 Removed FreezeSurface idx=-2 Map Size=4
08-20 11:24:06.750: INFO/SurfaceFlinger(223): id=6713 Removed BlackSurface idx=5 Map Size=4
08-20 11:24:06.750: INFO/OrientationDebug(293): [pwm] rotationForOrientationLw(), orientation=-1 lastRotation=1 userRotation=3
08-20 11:24:06.750: INFO/OrientationDebug(293): [pwm] useSensorForOrientationLp(), return true #2
08-20 11:24:06.750: INFO/OrientationDebug(293): [pwm] in rotationForOrientationLw(), return #13
08-20 11:24:06.760: INFO/SurfaceFlinger(223): id=6713 Removed BlackSurface idx=-2 Map Size=4
08-20 11:24:08.030: VERBOSE/WindowOrientationListener(293): rotation : 1   Angle: 90   tilt: -3
08-20 11:24:08.460: DEBUG/dalvikvm(293): GC_EXPLICIT freed 1140K, 16% free 116574K/137223K, paused 13ms+19ms
08-20 11:24:09.090: DEBUG/HierarchicalStateMachine(293): handleMessage: E msg.what=83
08-20 11:24:09.090: DEBUG/HierarchicalStateMachine(293): processMsg: ConnectedState
08-20 11:24:09.090: DEBUG/WifiStateMachine(293): ConnectedState{ what=83 when=-4ms arg1=936 }
08-20 11:24:09.110: DEBUG/HierarchicalStateMachine(293): handleMessage: X
08-20 11:24:09.500: VERBOSE/WindowOrientationListener(293): rotation : 1   Angle: 91   tilt: 2
08-20 11:24:11.380: DEBUG/dalvikvm(20510): GC_EXPLICIT freed 20K, 5% free 6220K/6531K, paused 2ms+9ms
08-20 11:24:12.120: DEBUG/HierarchicalStateMachine(293): handleMessage: E msg.what=83
08-20 11:24:12.120: DEBUG/HierarchicalStateMachine(293): processMsg: ConnectedState
08-20 11:24:12.120: DEBUG/WifiStateMachine(293): ConnectedState{ what=83 when=-4ms arg1=936 }
08-20 11:24:12.130: DEBUG/HierarchicalStateMachine(293): handleMessage: X

我希望这可以帮到你。

logcat并没有提供有用的信息,但是在上面更新的代码中有两个问题导致了你的问题。1:在调用setContentView(R.layout.login)之前,你试图设置flipper的位置;2:在初始化flipper之前,你引用了它。你必须先调用setContentView,然后flipper =(ViewFlipper)findViewById(R.id.cards);,最后检查savedInstanceState以设置flipper的位置。 - hooked82
哇,非常感谢你的帮助,现在代码可以工作了。看来我有一个倾向,就是在初始化之前尝试使用某些东西。 - Szymon Morawski
2个回答

10

通过重写onSaveInstanceState方法,在屏幕方向更改时尝试保存您所在的视图翻转器中的选项卡。

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    int position = flipper.getDisplayedChild();
    savedInstanceState.putInt("TAB_NUMBER", position);
}

然后在您的onCreate中,尝试以下操作

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState != null) {
        int flipperPosition = savedInstanceState.getInt("TAB_NUMBER");
        flipper.setDisplayedChild(flipperPosition);
    }
}

在调用setDisplayedChild()方法之前,确保您已经初始化了flipper,可以通过在onCreate()方法中执行类似以下内容的操作来实现:

flipper = (ViewFlipper) findViewById(R.id.flipper);

如果没有这样做可能会导致崩溃。


我尝试了你的代码,但由于某种原因,在方向更改时它会导致应用程序崩溃。我还是有点新手Android开发者,但当我在调试模式下运行它并将代码包围在Try Catch中时,似乎没有抛出任何异常,但也没有保存位置。如果没有Try Catch,它就会崩溃。 - Szymon Morawski
你能否在原帖中更新一些代码和错误发生时的logcat输出?这将有助于找出问题。 - hooked82
有人知道为什么需要这段代码吗?为什么翻转器或切换器的预期/默认行为是在方向改变时立即恢复到旧视图? - pete

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接