0
高さが常に40 dpになるカスタムビューを作成します。 通常の場合は正常に動作しますが、ソフトキーボードが表示されている場合は下にシフトします。
2番目の画面では、赤いボタンが下に移動して表示されますが、そのためのコードはありません。キーボードが表示された後にはじめて表示される
問題はandroid> = 5にあり、バージョン4.x.xにはこの問題はありません。
どのようにそれを取り除く?
レイアウトで
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dip"
android:orientation="horizontal"
android:layout_marginTop="16dip"
>
<ua.in.femid.view.widget.MyTextView
android:id="@+id/btn_deny"
android:layout_width="0dip"
android:layout_weight="210"
android:layout_height="40dip"
android:background="@drawable/bg_primary_stroke"
android:textColor="@color/request_deny"
android:text="@string/dr_back"
android:gravity="center"
style="@style/roboto_medium"
android:textAllCaps="true"
android:textSize="12dip"
android:clickable="true"
/>
<Space
android:layout_width="16dip"
android:layout_height="wrap_content"
/>
<ua.in.femid.view.widget.RoundButtonView
android:id="@+id/btn_confirm"
android:layout_width="0dip"
android:layout_weight="350"
android:layout_height="wrap_content"
app:color_end="@color/error_tapped"
app:color_start="@color/error_red_light"
android:text="@string/dr_confirm"
android:background="@android:color/transparent"
style="@style/roboto_medium"
android:textColor="@color/white"
android:textAllCaps="true"
android:textSize="12dip"
android:clickable="true"
/>
</LinearLayout>
ビュー自体
public class RoundButtonView extends Button {
private OnClickListener listener;
Paint mBgPaint;
private static final long ANIMATION_DURATION_MS = 250l;
RectF rectBG = new RectF();
private int minHeight = 0;
private float mPercent = 0f;
Matrix shaderMatrix;
int colorStart;
int colorEnd;
int cornerSize;
public RoundButtonView(Context context) {
super(context);
}
public RoundButtonView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public RoundButtonView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
shaderMatrix = new Matrix();
minHeight = (int) (40 * context.getResources().getDisplayMetrics().density);
cornerSize = (int) (20 * context.getResources().getDisplayMetrics().density);
mBgPaint = new Paint();
mBgPaint.setColor(Color.BLUE);
mBgPaint.setAntiAlias(true);
mBgPaint.setStyle(Paint.Style.FILL);
CustomFontHelper.setCustomFont(this, context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundButtonView);
ColorStateList startList = a.getColorStateList(R.styleable.RoundButtonView_color_start);
if (startList != null) {
colorStart = startList.getDefaultColor();
} else {
colorStart = Color.BLUE;
}
ColorStateList endList = a.getColorStateList(R.styleable.RoundButtonView_color_end);
if (endList != null) {
colorEnd = endList.getDefaultColor();
} else {
colorEnd = colorStart;
}
if (a.getBoolean(R.styleable.RoundButtonView_square, false)) {
cornerSize = 0;
}
a.recycle();
}
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int h = minHeight;
setMeasuredDimension(widthMeasureSpec, h);
rectBG.set(0, 0, MeasureSpec.getSize(widthMeasureSpec), h);
mBgPaint.setShader(
new LinearGradient(0, 0, 0, rectBG.bottom, colorStart, colorEnd, Shader.TileMode.MIRROR));
}
public void setColorStart(int colorRes) {
if (colorEnd != colorStart) {
colorStart = ContextCompat.getColor(getContext(), colorRes);
} else {
colorStart = ContextCompat.getColor(getContext(), colorRes);
colorEnd = colorStart;
}
mBgPaint.setShader(
new LinearGradient(0, 0, 0, rectBG.bottom, colorStart, colorEnd, Shader.TileMode.MIRROR));
invalidate();
}
@Override protected void onDraw(Canvas canvas) {
shaderMatrix.setTranslate(0, -rectBG.bottom * mPercent);
mBgPaint.getShader().setLocalMatrix(shaderMatrix);
canvas.drawRoundRect(rectBG, cornerSize, cornerSize, mBgPaint);
super.onDraw(canvas);
}
ValueAnimator animator;
@Override public void setOnClickListener(final OnClickListener onClickListener) {
RoundButtonView.this.setOnTouchListener(new OnTouchListener() {
@Override public boolean onTouch(final View v, MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_UP: {
if (event.getX() > 0 && event.getY() > 0 && event.getX() < rectBG.right
&& event.getY() < rectBG.bottom) {
long prevDuration = ANIMATION_DURATION_MS;
if (animator != null && animator.isRunning()) {
prevDuration = animator.getDuration();
animator.cancel();
}
invalidate();
animator = ValueAnimator.ofFloat(mPercent, 0);
animator.setInterpolator(new AccelerateDecelerateInterpolator());
animator.setDuration(prevDuration);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override public void onAnimationUpdate(ValueAnimator animation) {
setPercent((float) animation.getAnimatedValue());
}
});
animator.addListener(new Animator.AnimatorListener() {
@Override public void onAnimationStart(Animator animation) {
}
@Override public void onAnimationEnd(Animator animation) {
invalidate();
if (v != null) onClickListener.onClick(v);
}
@Override public void onAnimationCancel(Animator animation) {
invalidate();
}
@Override public void onAnimationRepeat(Animator animation) {
}
});
animator.start();
} else {
long prevDuration = ANIMATION_DURATION_MS;
if (animator != null && animator.isRunning()) {
prevDuration = animator.getDuration();
animator.cancel();
}
invalidate();
animator = ValueAnimator.ofFloat(mPercent, 0);
animator.setInterpolator(new AccelerateDecelerateInterpolator());
animator.setDuration(prevDuration);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override public void onAnimationUpdate(ValueAnimator animation) {
setPercent((float) animation.getAnimatedValue());
}
});
animator.addListener(new Animator.AnimatorListener() {
@Override public void onAnimationStart(Animator animation) {
}
@Override public void onAnimationEnd(Animator animation) {
invalidate();
}
@Override public void onAnimationCancel(Animator animation) {
invalidate();
}
@Override public void onAnimationRepeat(Animator animation) {
}
});
animator.start();
}
break;
}
case MotionEvent.ACTION_DOWN: {
long prevDuration = ANIMATION_DURATION_MS;
if (animator != null && animator.isRunning()) {
prevDuration = animator.getDuration();
animator.cancel();
}
invalidate();
animator = ValueAnimator.ofFloat(mPercent, 1);
animator.setInterpolator(new AccelerateDecelerateInterpolator());
animator.setDuration(prevDuration);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override public void onAnimationUpdate(ValueAnimator animation) {
setPercent((float) animation.getAnimatedValue());
}
});
animator.addListener(new Animator.AnimatorListener() {
@Override public void onAnimationStart(Animator animation) {
}
@Override public void onAnimationEnd(Animator animation) {
invalidate();
}
@Override public void onAnimationCancel(Animator animation) {
invalidate();
}
@Override public void onAnimationRepeat(Animator animation) {
}
});
animator.start();
}
break;
case MotionEvent.ACTION_CANCEL: {
break;
}
}
return true;
}
});
}
private void setPercent(float percent) {
mPercent = percent;
invalidate();
}
}