我开发了一个三窗格布局,一次最多可以看到两个窗格。仅在横向模式下支持多个视图。每个窗格都包含用于更改可见性状态的箭头,因此窗格分布会发生变化。
当应用程序以纵向模式打开时,视图转换正常工作。当应用程序以横向模式打开时,也会发生同样的情况。当设备旋转并且控件应该改变面板的分布时会出现问题。当设备旋转时,状态转换失败,窗格消失或不在应有的位置。
由于应用程序的要求,活动主机自己处理配置更改(android:configChanges="orientation|screensize"
),我无法禁用此行为。当onConfigurationChanged
在宿主活动中调用方法时,通知控件执行状态转换。根据当前可见性状态和新方向,控件确定新状态并调用负责执行转换的configureWidth
方法(控件代码中的方法)。下面是宿主活动和控件的代码:
MainActivity.java
public class MainActivity extends Activity implements
CategoriesListFragment.OnCategoriesListSizeControlListener,
TasksListFragment.OnTasksListSizeControlListener,
TaskDetailFragment.OnTaskDetailSizeControlListener, OnStateChangeListener {
// Multipanel control that will contain the fragments associated with the
// category list, task list and task detail.
private ThreePaneLayout mMultiPaneControl;
// Fragments
private CategoriesListFragment mCategoriesListFragment;
private TasksListFragment mTasksListFragment;
private TaskDetailFragment mTaskDetailFragment;
private int mScreenOrientation;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Get the initial orientation of the device
mScreenOrientation = getResources().getConfiguration().orientation;
mMultiPaneControl = (ThreePaneLayout) findViewById(R.id.multiPaneControl);
mCategoriesListFragment = CategoriesListFragment.newInstance();
mTasksListFragment = TasksListFragment.newInstance();
mTaskDetailFragment = TaskDetailFragment.newInstance();
// Add the state change observers of the ThreePaneLayout control.
// The client fragments use the events of the OnstateChangeListener interface to
// update the arrows orientation that user can use to redimension the panels
mMultiPaneControl.addStateObserver(mCategoriesListFragment);
mMultiPaneControl.addStateObserver(mTasksListFragment);
mMultiPaneControl.addStateObserver(mTaskDetailFragment);
mMultiPaneControl.addStateObserver(this);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.add(R.id.categoriesList, mCategoriesListFragment, "tag");
transaction.add(R.id.tasksList, mTasksListFragment);
transaction.add(R.id.taskDetail, mTaskDetailFragment);
transaction.commit();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mScreenOrientation = getResources().getConfiguration().orientation;
// When device orientationcchange notify the ThreePaneLyout control associated with the activity
// to update the distribution of its panels in order to improve usability
mMultiPaneControl.deviceOrientationHasChange();
}
@Override
public void onCategoriesListSizeControlSelected() {
if (mScreenOrientation == Configuration.ORIENTATION_LANDSCAPE) {
VisibilityState visibilityState = mMultiPaneControl.getVisibityState();
if (visibilityState == VisibilityState.LEFT_AND_MIDDLE_VISIBLE ) {
mMultiPaneControl.setVisibilityState(VisibilityState.LEFT_VISIBLE);
} else if ( visibilityState == VisibilityState.LEFT_VISIBLE) {
mMultiPaneControl.setVisibilityState(VisibilityState.LEFT_AND_MIDDLE_VISIBLE);
}
} else { // Configuration.ORIENTATION_PORTRAIT
// The only possible state if this event is received while the device in
// portrait orientation is MIDDLE_VISIBLE
mMultiPaneControl.setVisibilityState(VisibilityState.MIDDLE_VISIBLE);
}
}
@Override
public void onTasksListSizeControlSelected(boolean leftControl) {
VisibilityState visibilityState = mMultiPaneControl.getVisibityState();
if (leftControl) {
if ( mScreenOrientation == Configuration.ORIENTATION_LANDSCAPE ) {
if (visibilityState == VisibilityState.LEFT_AND_MIDDLE_VISIBLE ) {
mMultiPaneControl.setVisibilityState(VisibilityState.MIDDLE_VISIBLE);
} else if (visibilityState == VisibilityState.MIDDLE_VISIBLE ) {
mMultiPaneControl.setVisibilityState(VisibilityState.LEFT_AND_MIDDLE_VISIBLE);
} else if (visibilityState == VisibilityState.MIDDLE_AND_RIGHT_VISIBLE ) {
mMultiPaneControl.setVisibilityState(VisibilityState.LEFT_AND_MIDDLE_VISIBLE);
}
} else { // Configuration.ORIENTATION_PORTRAIT
// The only possible state if this event is received while the device in
// portrait orientation is LEFT_VISIBLE
mMultiPaneControl.setVisibilityState(VisibilityState.LEFT_VISIBLE);
}
} else {
if (mScreenOrientation == Configuration.ORIENTATION_LANDSCAPE) {
if (visibilityState == VisibilityState.LEFT_AND_MIDDLE_VISIBLE) {
mMultiPaneControl.setVisibilityState(VisibilityState.MIDDLE_AND_RIGHT_VISIBLE);
} else if (visibilityState == VisibilityState.MIDDLE_VISIBLE) {
mMultiPaneControl.setVisibilityState(VisibilityState.MIDDLE_AND_RIGHT_VISIBLE);
} else if (visibilityState == VisibilityState.MIDDLE_AND_RIGHT_VISIBLE) {
mMultiPaneControl.setVisibilityState(VisibilityState.MIDDLE_VISIBLE);
}
} else { // Configuration.ORIENTATION_PORTRAIT
// The only possible state if this event is received while the device in
// portrait orientation is RIGHT_VISIBLE
mMultiPaneControl.setVisibilityState(VisibilityState.RIGHT_VISIBLE);
}
}
}
@Override
public void onDetailTaskSizeControlSelected() {
VisibilityState visibilityState = mMultiPaneControl.getVisibityState();
if (mScreenOrientation == Configuration.ORIENTATION_LANDSCAPE) {
if ( visibilityState == VisibilityState.MIDDLE_AND_RIGHT_VISIBLE) {
mMultiPaneControl.setVisibilityState(VisibilityState.RIGHT_VISIBLE);
} else if ( visibilityState == VisibilityState.RIGHT_VISIBLE) {
mMultiPaneControl.setVisibilityState(VisibilityState.MIDDLE_AND_RIGHT_VISIBLE);
}
} else { // Configuration.ORIENTATION_PORTRAIT
// The only possible state if this event is received while the device in
// portrait orientation is MIDDLE_VISIBLE
mMultiPaneControl.setVisibilityState(VisibilityState.MIDDLE_VISIBLE);
}
}
@Override
public void onBeginTransitionState(VisibilityState oldState,
VisibilityState newState) {
}
@Override
public void onNewStateVisible(VisibilityState newState) { /**/ }
}
ThreePaneLayout.java
/**
* <p>Control to display up to three panels with a maximum of two simultaneously visible.</p>
*/
public class ThreePaneLayout extends LinearLayout {
/**
* Time control takes for the state change animation
*/
public static final int ANIMATION_DURATION = 300;
private boolean isScrollingViews;
/**
* Possible control visibility states. The states are exclusive, ie, if the control is
* in state {@ link LEFT_AND_MIDDLE_VISIBLE} implies that the right pane is not visible.
*/
public enum VisibilityState {
LEFT_VISIBLE,
LEFT_AND_MIDDLE_VISIBLE,
MIDDLE_VISIBLE,
MIDDLE_AND_RIGHT_VISIBLE,
RIGHT_VISIBLE
}
/**
* Interface to be implemented by clients that require to be notified
* when the visibility state change.
*/
public interface OnStateChangeListener {
/**
* Method invoked by the control just prior to the transition state of visibility
*
* @param oldState Estado actual de visibilidad control
* @param newState Proximo estado de visibilidad del control
*/
void onBeginTransitionState(VisibilityState oldState, VisibilityState newState);
/**
* Method invoked by the control when its visibility status has been updated
*
* @param newState New visibility state of the control panels
*/
void onNewStateVisible(VisibilityState newState);
}
// Reference to the three panels of the control
private View mLeftView;
private View mMiddleView;
private View mRightView;
// Variables that store the minimum and maximum widths that can have different panels
private int mMinPaneWidth = -1;
private int mMaxPaneWidth;
private int mFullScreenWidth;
// Stores the current device orientation
private int mScreenOrientation;
// Reference to the current state of the panels
private VisibilityState mVisibilityState;
/**
* Lista de observadores de cambio de estado del control
*/
private List<OnStateChangeListener> mStateListeners;
private Handler mHandler = new Handler();
private Context mContext;
public ThreePaneLayout(Context context, AttributeSet attrs) {
super(context, attrs);
Log.i("Log", "Llamado el constructor del control");
mContext = context;
mScreenOrientation = getResources().getConfiguration().orientation;
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
setOrientation(HORIZONTAL);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ThreePaneLayout);
String initialState = a.getString(R.styleable.ThreePaneLayout_initialState);
if ( initialState != null ) {
// The initial state has been defined in the XML
if (initialState.equals("left_visible")) {
mVisibilityState = VisibilityState.LEFT_VISIBLE;
} else if (initialState.equals("left_and_middle_visible")) {
mVisibilityState = VisibilityState.LEFT_AND_MIDDLE_VISIBLE;
}
} else {
// The initial state is not defined in the XML, set the default state
mVisibilityState = VisibilityState.LEFT_AND_MIDDLE_VISIBLE;
}
}
@Override
public void onFinishInflate() {
super.onFinishInflate();
if ( getChildCount() != 3 ) {
throw new IllegalStateException("ThreePaneLayout requires defining three daughters views in the XML");
}
// Get a reference to the views that make control
mLeftView = getChildAt(0);
mMiddleView = getChildAt(1);
mRightView = getChildAt(2);
configureWidth();
}
/**
* Set the weights of each of the views of the layout container.
*
* If the method takes no arguments recalculates the weights based on the current visibility
* state of the control. If this method receive a parameter is used as visibility state from
* which will be held on recalculation
*
* @param args
*/
private void configureWidth(VisibilityState ... args) {
LayoutParams leftPaneLayoutParams = (LayoutParams) mLeftView.getLayoutParams();
LayoutParams middlePaneLayoutParams = (LayoutParams) mMiddleView.getLayoutParams();
LayoutParams rightPaneLayoutParams = (LayoutParams) mRightView.getLayoutParams();
VisibilityState visibilityState = args.length == 0 ? mVisibilityState : args[0];
if (args.length > 0) {
leftPaneLayoutParams.width = 0;
middlePaneLayoutParams.width = 0;
rightPaneLayoutParams.width = 0;
}
if ( visibilityState == VisibilityState.LEFT_VISIBLE ) {
leftPaneLayoutParams.weight = 1.0f;
middlePaneLayoutParams.weight = 0.0f;
rightPaneLayoutParams.weight = 0.0f;
} else if ( visibilityState == VisibilityState.LEFT_AND_MIDDLE_VISIBLE ) {
leftPaneLayoutParams.weight = 0.35f;
middlePaneLayoutParams.weight = 0.65f;
rightPaneLayoutParams.weight = 0.0f;
} else if ( visibilityState == VisibilityState.MIDDLE_VISIBLE ) {
leftPaneLayoutParams.weight = 0.0f;
middlePaneLayoutParams.weight = 1.0f;
rightPaneLayoutParams.weight = 0.0f;
} else if ( visibilityState == VisibilityState.MIDDLE_AND_RIGHT_VISIBLE ) {
leftPaneLayoutParams.weight = 0.0f;
middlePaneLayoutParams.weight = 0.35f;
rightPaneLayoutParams.weight = 0.65f;
} else if ( visibilityState == VisibilityState.RIGHT_VISIBLE ) {
leftPaneLayoutParams.weight = 0.0f;
middlePaneLayoutParams.weight = 0.0f;
rightPaneLayoutParams.weight = 1.0f;
}
// Refresh the view and compute the size of the view in the screen.
requestLayout();
}
/**
* Method that performs the visibility state transition control (redistribution of the panels)
*
* @param newVisibilityState New visibility state required.
* @param resetDimensions This parameter is optional and should be used only when you are performing a
* state transcion due to a change of device orientation so we can recalculated
* weights and widths of the panels.
*/
public void setVisibilityState(VisibilityState newVisibilityState, boolean ... resetDimensions) {
// Ignore the request if the control is being resized or if the requested state is equal to the current
if ( isScrollingViews || newVisibilityState == mVisibilityState ) {
return;
}
// If requested any state that contains more than one panel and device orientation is portrait,
// ignore the request (this control only supports multiple panels visible in landscape)
if (mScreenOrientation == Configuration.ORIENTATION_PORTRAIT) {
if ( newVisibilityState == VisibilityState.LEFT_AND_MIDDLE_VISIBLE ||
newVisibilityState == VisibilityState.MIDDLE_AND_RIGHT_VISIBLE ) {
return;
}
}
if (resetDimensions.length > 0 && resetDimensions[0] == true) {
configureWidth(newVisibilityState);
mMinPaneWidth = -1;
}
// Calculate the maximum and minimum widths of the control panel if the have not been defined
if (mMinPaneWidth == -1) {
DisplayMetrics displayMetrics = new DisplayMetrics();
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics(displayMetrics);
int screenWidth = displayMetrics.widthPixels;
if ( mScreenOrientation == Configuration.ORIENTATION_LANDSCAPE ) {
mMinPaneWidth = (int) (screenWidth * 0.35);
mMaxPaneWidth = screenWidth - mMinPaneWidth;
mFullScreenWidth = screenWidth;
} else { // Configuration.ORIENTATION_PORTRAIT
mMinPaneWidth = mMaxPaneWidth = mFullScreenWidth = screenWidth;
}
resetWidget(mLeftView, mMinPaneWidth);
resetWidget(mMiddleView, mMaxPaneWidth);
resetWidget(mRightView, mMaxPaneWidth);
requestLayout();
}
isScrollingViews = true;
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
isScrollingViews = false;
}
}, ANIMATION_DURATION + 100);
VisibilityState currentVisibilityState = mVisibilityState;
// Notify control observers will produce a state transition
if ( mStateListeners != null ) {
for ( OnStateChangeListener observer : mStateListeners ) {
observer.onBeginTransitionState(currentVisibilityState, newVisibilityState);
}
}
if (resetDimensions.length == 0) {
// Perform the movement of the panels to match the new state required
animateVisibilityStateTransition(currentVisibilityState, newVisibilityState);
}
// Update the reference to the current state
mVisibilityState = newVisibilityState;
// Notify the new control state to the control's observers
if ( mStateListeners != null ) {
for ( OnStateChangeListener observer : mStateListeners ) {
observer.onNewStateVisible(mVisibilityState);
}
}
}
/**
* Moves on the x axis and resize the panels to suit new visibility state required.
*
* @param currentVisibilityState Current state control visibility
* @param requiredVisibilityState New visibility state required
*/
private void animateVisibilityStateTransition(VisibilityState currentVisibilityState,
VisibilityState requiredVisibilityState) {
switch (requiredVisibilityState) {
case LEFT_VISIBLE:
if (mScreenOrientation == Configuration.ORIENTATION_LANDSCAPE) {
if (currentVisibilityState == VisibilityState.LEFT_AND_MIDDLE_VISIBLE) {
ObjectAnimator.ofInt(this, "leftWidth", mMinPaneWidth, mFullScreenWidth)
.setDuration(ANIMATION_DURATION).start();
}
} else { // Configuration.ORIENTATION_PORTRAIT
if (currentVisibilityState == VisibilityState.MIDDLE_VISIBLE) {
translateView(mMaxPaneWidth, mLeftView, mMiddleView, mRightView);
} else if (currentVisibilityState == VisibilityState.RIGHT_VISIBLE) {
translateView(2 * mMaxPaneWidth, mLeftView, mMiddleView, mRightView);
}
}
break;
case LEFT_AND_MIDDLE_VISIBLE:
// Este estado solo es posible en orientacion panoramica
if (currentVisibilityState == VisibilityState.MIDDLE_VISIBLE) {
translateView(mMinPaneWidth, mLeftView, mMiddleView, mRightView);
ObjectAnimator.ofInt(this, "middleWidth", mFullScreenWidth, mMaxPaneWidth)
.setDuration(ANIMATION_DURATION).start();
} else if (currentVisibilityState == VisibilityState.MIDDLE_AND_RIGHT_VISIBLE) {
translateView(mMinPaneWidth, mLeftView, mMiddleView, mRightView);
ObjectAnimator.ofInt(this, "middleWidth", mMinPaneWidth, mMaxPaneWidth)
.setDuration(ANIMATION_DURATION).start();
} else if (currentVisibilityState == VisibilityState.LEFT_VISIBLE) {
ObjectAnimator.ofInt(this, "leftWidth", mFullScreenWidth, mMinPaneWidth)
.setDuration(ANIMATION_DURATION).start();
}
break;
case MIDDLE_VISIBLE:
if (mScreenOrientation == Configuration.ORIENTATION_LANDSCAPE) {
if (currentVisibilityState == VisibilityState.LEFT_AND_MIDDLE_VISIBLE) {
translateView(-1 * mMinPaneWidth, mLeftView, mMiddleView, mRightView);
ObjectAnimator.ofInt(this, "middleWidth", mMaxPaneWidth, mFullScreenWidth)
.setDuration(ANIMATION_DURATION).start();
} else if (currentVisibilityState == VisibilityState.MIDDLE_AND_RIGHT_VISIBLE) {
ObjectAnimator.ofInt(this, "middleWidth", mMinPaneWidth, mFullScreenWidth)
.setDuration(ANIMATION_DURATION).start();
}
} else { // Configuration.ORIENTATION_PORTRAIT
if (currentVisibilityState == VisibilityState.LEFT_VISIBLE) {
translateView(-1 * mMaxPaneWidth, mLeftView, mMiddleView, mRightView);
} else if (currentVisibilityState == VisibilityState.RIGHT_VISIBLE) {
translateView(mMaxPaneWidth, mLeftView, mMiddleView, mRightView);
}
}
break;
case MIDDLE_AND_RIGHT_VISIBLE:
// Este estado solo es posible en orientacion panoramica
if (currentVisibilityState == VisibilityState.LEFT_AND_MIDDLE_VISIBLE) {
translateView(-1 * mMinPaneWidth, mLeftView, mMiddleView, mRightView);
ObjectAnimator.ofInt(this, "middleWidth", mMaxPaneWidth, mMinPaneWidth)
.setDuration(ANIMATION_DURATION).start();
} else if (currentVisibilityState == VisibilityState.MIDDLE_VISIBLE) {
ObjectAnimator.ofInt(this, "middleWidth", mFullScreenWidth, mMinPaneWidth)
.setDuration(ANIMATION_DURATION).start();
} else if (currentVisibilityState == VisibilityState.RIGHT_VISIBLE) {
translateView(mMinPaneWidth, mLeftView, mMiddleView, mRightView);
ObjectAnimator.ofInt(this, "rightWidth", mFullScreenWidth, mMaxPaneWidth)
.setDuration(ANIMATION_DURATION).start();
}
break;
case RIGHT_VISIBLE:
if (mScreenOrientation == Configuration.ORIENTATION_LANDSCAPE) {
if (currentVisibilityState == VisibilityState.MIDDLE_AND_RIGHT_VISIBLE) {
translateView(-1 * mMinPaneWidth, mLeftView, mMiddleView, mRightView);
ObjectAnimator.ofInt(this, "rightWidth", mMaxPaneWidth, mFullScreenWidth)
.setDuration(ANIMATION_DURATION).start();
}
} else { // Configuration.ORIENTATION_PORTRAIT
if (currentVisibilityState == VisibilityState.LEFT_VISIBLE) {
translateView(-2 * mMaxPaneWidth, mLeftView, mMiddleView, mRightView);
} else if (currentVisibilityState == VisibilityState.MIDDLE_VISIBLE) {
translateView(-1 * mMaxPaneWidth, mLeftView, mMiddleView, mRightView);
}
}
break;
}
}
public VisibilityState getVisibityState() {
return mVisibilityState;
}
@SuppressWarnings("unused")
private void setLeftWidth(int value) {
mLeftView.getLayoutParams().width = value;
requestLayout();
}
@SuppressWarnings("unused")
private void setMiddleWidth(int value) {
mMiddleView.getLayoutParams().width = value;
requestLayout();
}
@SuppressWarnings("unused")
private void setRightWidth(int value) {
mRightView.getLayoutParams().width = value;
requestLayout();
}
/**
* Moves in the X axis the views received as parameter.
*
* @param deltaX Number of pixels that are shifted in the x-axis views
* @param views Views on which it will move
*/
private void translateView(int deltaX, View... views) {
for (final View view : views) {
view.setLayerType(View.LAYER_TYPE_NONE, null);
view.animate().translationXBy(deltaX).setDuration(ANIMATION_DURATION)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
view.setLayerType(View.LAYER_TYPE_NONE, null);
}
});
}
}
/**
* Updates the properties of length and weight on the layout of the view passed as parameter
*
* @param view Vista on which perform the update of the properties
* @param width New width
*/
private void resetWidget(View view, int width) {
LinearLayout.LayoutParams p = (LinearLayout.LayoutParams) view.getLayoutParams();
p.width = width;
p.weight = 0;
}
/**
* Adds the component passed as a parameter to the list of control observers. The observers are notified
* every time the control change the panels distribution. Observers also receive a notification just before
* starting the transition state by the control.
*
* @param observer component that implements the {@ link OnStateChangeListener} interface
* to recieve notifications when the visibility control state change
*/
public void addStateObserver(OnStateChangeListener observer) {
if ( mStateListeners == null ) {
mStateListeners = new ArrayList<OnStateChangeListener>();
}
mStateListeners.add(observer);
}
/**
* Removes the component passed as parameter from the list of observers of
* state change. Observers are added to the list through the method {@ link # addStateObserver}
*
* @param observer component that implements the {@ link OnStateChangeListener} interface
* to recieve notifications when the visibility control state change
*/
public void deleteStatetObserver(OnStateChangeListener observer) {
if ( mStateListeners == null ) return;
mStateListeners.remove(observer);
}
/**
* Method invoked by the host activity when the orientation of the device has changed. Based on the
* new orientation the control redistributes panels to match the new orientation and improve usability
*/
public void deviceOrientationHasChange()
{
int newScreenOrientation = getResources().getConfiguration().orientation;
VisibilityState currentVisibilityState = getVisibityState();
VisibilityState newVisibilityState = null;
if (newScreenOrientation == Configuration.ORIENTATION_LANDSCAPE) {
// When orientation chamge to landscape the only possible states in the previous orientation
// (portrait) can only be those where not coexist multiple views (eg LEFT_VISIBLE,
// MIDDLE_VISIBLE, RIGHT_VISIBLE)
if (currentVisibilityState == VisibilityState.LEFT_VISIBLE) {
newVisibilityState = VisibilityState.LEFT_AND_MIDDLE_VISIBLE;
} else if (currentVisibilityState == VisibilityState.MIDDLE_VISIBLE) {
newVisibilityState = VisibilityState.MIDDLE_VISIBLE;
} else if (currentVisibilityState == VisibilityState.RIGHT_VISIBLE) {
newVisibilityState = VisibilityState.RIGHT_VISIBLE;
}
} else { // Configuration.ORIENTATION_PORTRAIT
if (currentVisibilityState == VisibilityState.LEFT_VISIBLE) {
newVisibilityState = VisibilityState.LEFT_VISIBLE;
} else if ( currentVisibilityState == VisibilityState.LEFT_AND_MIDDLE_VISIBLE ||
currentVisibilityState == VisibilityState.MIDDLE_VISIBLE ) {
newVisibilityState = VisibilityState.MIDDLE_VISIBLE;
} else if (currentVisibilityState == VisibilityState.MIDDLE_AND_RIGHT_VISIBLE) {
newVisibilityState = VisibilityState.RIGHT_VISIBLE;
} else if (currentVisibilityState == VisibilityState.RIGHT_VISIBLE) {
newVisibilityState = VisibilityState.RIGHT_VISIBLE;
}
}
mScreenOrientation = newScreenOrientation;
mMinPaneWidth = -1;
configureWidth(newVisibilityState);
mVisibilityState = newVisibilityState;
}
public View getLeftView() {
return mLeftView;
}
public View getMiddleView() {
return mMiddleView;
}
public View getRightView() {
return mRightView;
}
}
例如,当设备处于横向且可见性状态为 MIDDLE AND RIGHT(参见图 1)时,当您将设备旋转为纵向时,状态更改将失败(参见图 2)。
图1
图 2
为了对应用程序进行更详细的分析,我在 github 上发布了一个使用该控件的示例应用程序,可从以下链接下载:https ://github.com/dfpalomar/ThreePaneLayout
我尝试使用 methods和控件的 configureWidth 方法强制重绘视图,但没有得到预期的结果requestLayout
。invalidate
forceLayout
欢迎任何关于我如何解决问题的建议:D