Özel bir görünümün hangi yüksekliğin her zaman 40 dp olması gerektiğini gösteririm. Normal durumlarda iyi çalışır, ancak yumuşak klavye gösterildiğinde aşağı kaydırılır.
İkinci ekran gösterisinde görünür, bu kırmızı düğme aşağı kaydırılır, ancak bunun için bir kod yoktur.Klavyenin gösterildikten sonra yanlış yerleştirilmiş görünümü
Sorun android'de mevcut => 5, sürüm 4.x.x'de bu sorun yok.
Bundan nasıl kurtulabiliriz? düzende
<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>
Görünüm kendisi
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();
}
}