-
Notifications
You must be signed in to change notification settings - Fork 687
/
KPSwitchPanelLayoutHandler.java
208 lines (184 loc) · 7.38 KB
/
KPSwitchPanelLayoutHandler.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
/*
* Copyright (C) 2015-2017 Jacksgong(blog.dreamtobe.cn)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.dreamtobe.kpswitch.handler;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import cn.dreamtobe.kpswitch.IPanelConflictLayout;
import cn.dreamtobe.kpswitch.R;
import cn.dreamtobe.kpswitch.util.ViewUtil;
/**
* Created by Jacksgong on 3/30/16.
* <p/>
* Keyboard->Panel: if the keyboard is showing, and {@code visibility} equal {@link View#VISIBLE}
* then must by Keyboard->Panel, then show the panel after the keyboard is real gone, and will be
* show by {@link IPanelConflictLayout#handleShow()}.
* Easy and Safe way: {@link cn.dreamtobe.kpswitch.util.KPSwitchConflictUtil#showPanel(View)}.
* <p/>
* Panel->Keyboard: do not need to invoke {@link View#setVisibility(int)} to let the panel gone,
* just show keyboard, the panel will be gone automatically when keyboard is real visible, and will
* be hide by {@link #handleHide()} -> {@link #processOnMeasure(int, int)}.
* Easy and safe way:
* {@link cn.dreamtobe.kpswitch.util.KPSwitchConflictUtil#showKeyboard(View, View)}.
*
* @see cn.dreamtobe.kpswitch.widget.KPSwitchPanelFrameLayout
* @see cn.dreamtobe.kpswitch.widget.KPSwitchPanelLinearLayout
* @see cn.dreamtobe.kpswitch.widget.KPSwitchPanelRelativeLayout
*/
public class KPSwitchPanelLayoutHandler implements IPanelConflictLayout {
private final View panelLayout;
/**
* The real status of Visible or not
*
* @see #handleHide()
* @see #filterSetVisibility(int) (int)
* <p/>
* if true, the status is non-Visible or will
* non-Visible(may delay and handle in {@link #processOnMeasure(int, int)})
* <p/>
* The value of {@link View#getVisibility()} maybe be assigned dully for cover the
* keyboard->panel.
* In this case, the {@code mIsHide} will mark the right status.
* Handle by {@link #filterSetVisibility(int)} & {@link #processOnMeasure(int, int)}
*/
private boolean mIsHide = false;
/**
* Whether ignore the recommend panel height, what would be equal to the height of keyboard in
* most situations.
* <p/>
* If the value is true, the panel's height will not be follow the height of the keyboard.
* <p/>
* Default is false.
*
* @attr ref cn.dreamtobe.kpswitch.R.styleable#KPSwitchPanelLayout_ignore_recommend_height
*/
@SuppressWarnings("JavaDoc")
private boolean mIgnoreRecommendHeight = false;
public KPSwitchPanelLayoutHandler(final View panelLayout, final AttributeSet attrs) {
this.panelLayout = panelLayout;
if (attrs != null) {
TypedArray typedArray = null;
try {
typedArray = panelLayout.getContext().
obtainStyledAttributes(attrs, R.styleable.KPSwitchPanelLayout);
mIgnoreRecommendHeight = typedArray.
getBoolean(R.styleable.KPSwitchPanelLayout_ignore_recommend_height,
false);
} finally {
if (typedArray != null) {
typedArray.recycle();
}
}
}
}
/**
* Filter the {@link View#setVisibility(int)} for handling Keyboard->Panel.
*
* @param visibility {@link View#setVisibility(int)}
* @return whether filtered out or not.
*/
public boolean filterSetVisibility(final int visibility) {
if (visibility == View.VISIBLE) {
this.mIsHide = false;
}
if (visibility == panelLayout.getVisibility()) {
return true;
}
/**
* For handling Keyboard->Panel.
*
* Will be handled on {@link KPSwitchRootLayoutHandler#handleBeforeMeasure(int, int)} ->
* {@link IPanelConflictLayout#handleShow()} Delay show, until the
* {@link KPSwitchRootLayoutHandler} discover
* the size is changed by keyboard-show. And will show, on the next frame of the above
* change discovery.
*/
//noinspection RedundantIfStatement
if (isKeyboardShowing() && visibility == View.VISIBLE) {
return true;
}
return false;
}
/**
* Handle Panel -> Keyboard.
* <p/>
* Process the {@link View#onMeasure(int, int)} for handling the case of Panel->Keyboard.
*
* @return the processed measure-width-spec and measure-height-spec.
* @see #handleHide()
*/
public int[] processOnMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mIsHide) {
panelLayout.setVisibility(View.GONE);
/*
* The current frame will be visible nil.
*/
widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.EXACTLY);
heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.EXACTLY);
}
final int[] processedMeasureWHSpec = new int[2];
processedMeasureWHSpec[0] = widthMeasureSpec;
processedMeasureWHSpec[1] = heightMeasureSpec;
return processedMeasureWHSpec;
}
private boolean mIsKeyboardShowing = false;
public void setIsKeyboardShowing(final boolean isKeyboardShowing) {
mIsKeyboardShowing = isKeyboardShowing;
}
@Override
public boolean isKeyboardShowing() {
return mIsKeyboardShowing;
}
@Override
public boolean isVisible() {
return !mIsHide;
}
@Override
public void handleShow() {
throw new IllegalAccessError("You can't invoke handle show in handler,"
+ " please instead of handling in the panel layout, maybe just need invoke "
+ "super.setVisibility(View.VISIBLE)");
}
/**
* @see #processOnMeasure(int, int)
*/
@Override
public void handleHide() {
this.mIsHide = true;
}
/**
* @param recommendPanelHeight the recommend panel height, in the most situations, the value
* would be equal to the height of the keyboard.
* @see cn.dreamtobe.kpswitch.util.KeyboardUtil#getValidPanelHeight
*/
public void resetToRecommendPanelHeight(int recommendPanelHeight) {
if (mIgnoreRecommendHeight) {
// In this way, the panel's height will be not follow the height of keyboard.
return;
}
ViewUtil.refreshHeight(panelLayout, recommendPanelHeight);
}
/**
* @param ignoreRecommendHeight Whether ignore the recommend panel height, what would be equal
* to the height of keyboard in most situations.
* @attr ref cn.dreamtobe.kpswitch.R.styleable#KPSwitchPanelLayout_ignore_recommend_height
* @see #resetToRecommendPanelHeight(int)
*/
@SuppressWarnings("JavaDoc")
public void setIgnoreRecommendHeight(boolean ignoreRecommendHeight) {
this.mIgnoreRecommendHeight = ignoreRecommendHeight;
}
}