如何在更改方向时保持ViewFlipper中的当前视图

时间:2011-08-19 07:37:34

标签: android user-interface orientation viewflipper

是否有任何好方法可以在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

我希望这会有所帮助。

2 个答案:

答案 0 :(得分:9)

通过覆盖onSaveInstanceState

,尝试在屏幕方向发生变化时保存ViewFlipper中的哪个标签页
@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 = (ViewFlipper) findViewById(R.id.flipper);

在你的onCreate()方法中

。不这样做可能会导致崩溃。

答案 1 :(得分:0)

除了自己保存应用程序状态并在屏幕方向更改后加载它之外别无他法。您可以覆盖onRetainNonConfigurationInstance()方法,或者如果您使用API​​ 11或更新版,请使用setRetainInstance(boolean)getLastNonConfigurationInstance()

Here is也回答是否使用保留实例或保存它。

您也有可能自己夸大新的端口布局,但我认为这不是一个好主意。