Android 一个美观简洁的登录界面(一) | 您所在的位置:网站首页 › 安卓怎么拍照好看 › Android 一个美观简洁的登录界面(一) |
Android 一个美观简洁的登录界面 输入框样式 一.登录式样1: 1.效果图: 2.布局代码: 3.设置AppCompatEditText(EditText)的下划线和光标显示的颜色,自定义默认和选中的颜色设置: 在style中配置 @color/white @color/colorConfirm4.android:textCursorDrawable 自定义光标样式,设置为”@null”之后发现光标的样式会变得跟文字的颜色一样 5.5.0一下的手机显示下划线可以会有问题,Material Design风格体现不出来,可以这样处理: 设置选择状态: et_underline_unselected.xml et_underline_selected.xml /**初始化EditText,默认都为未选中状态**/ editText1.setBackgroundResource(R.drawable.et_underline_unselected); editText2.setBackgroundResource(R.drawable.et_underline_unselected); /**第一个EditText的焦点监听事件**/ editText1.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { Log.e(TAG, "EditText1获得焦点"); editText1.setBackgroundResource(R.drawable.et_underline_selected); } else { Log.e(TAG, "EditText1失去焦点"); editText1.setBackgroundResource(R.drawable.et_underline_unselected); } } }); /**第二个EditText的焦点监听事件**/ editText2.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { Log.e(TAG, "EditText2获得焦点"); editText2.setBackgroundResource(R.drawable.et_underline_selected); } else { Log.e(TAG, "EditText2失去焦点"); editText2.setBackgroundResource(R.drawable.et_underline_unselected); } } });二.登录式样2: 1.效果图: 2.布局代码: 圆角背景 要是你想使用圆角背景渐变色的话可以看看下面: 其中 android:angle="270" 代表方向, 270表示从上到下,180表示从右到左,默认从左 在这里要注意android:type="radial"类型的使用会有不同的效果,android:centerColor="#FFd4e9a9" 通常这个也不是被人常用 Android背景色渐变(左上->右下)在这里设置背景上下渐变色 设置背景左右渐变色都是可以的 android:shape 配置的是图形的形式,主要包括方形、圆形等,上边代码为方形。gradient节点主要配置起点颜色、终点颜色、中间点的坐标、中间点的颜色、渐变角度(90度为上下渐变,0为左右渐变),padding节点主要配置上下左右边距,corners节点配置四周园角的半径。 三.登录式样三(EditText、TextInputLayout、AppCompatEditText、ClearEditText等) 1.布局: 2.属性: @color/white @color/colorConfirm @color/gray @color/gray @color/colorAccent @color/colorAccent true @color/red #00aaff 16spbg_edittext.xml bt_blue.xml 3.主函数代码: import android.os.Bundle; import android.support.design.widget.TextInputLayout; import android.support.v7.app.AppCompatActivity; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.view.View; import android.widget.EditText; import com.example.m1571.mycolorfulnews.R; import butterknife.ButterKnife; /** * 登录输入框 */ public class TextInputLayoutActivity extends AppCompatActivity { private TextInputLayout textinputlayout_email; private TextInputLayout textinputlayout_name; private TextInputLayout textinputlayout_password; private TextInputLayout textinputlayout_code; private EditText et_email; private EditText et_name; private EditText et_password; private EditText et_code; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_textinputlayout); ButterKnife.bind(this); et_name = findViewById(R.id.et_name); et_email = findViewById(R.id.et_email); et_password = findViewById(R.id.et_password); et_code = findViewById(R.id.et_code); textinputlayout_name = findViewById(R.id.textinputlayout_name); textinputlayout_email = findViewById(R.id.textinputlayout_email); textinputlayout_password = findViewById(R.id.textinputlayout_password); textinputlayout_code = findViewById(R.id.textinputlayout_code); et_email.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { // if (!RegexUtils.isEmail(charSequence)) { // textInputLayout.setError("邮箱格式错误"); // textInputLayout.setErrorEnabled(true); // } else { // textInputLayout.setErrorEnabled(false); // } if (!isValidEmail(et_email.getText())) { // edittext2.setError("Email is invalid"); // textInputLayout2.setError("Email is invalid"); textinputlayout_email.setError("邮箱格式错误"); textinputlayout_email.setErrorEnabled(true); } else { // textinputlayout_email.setError(null); textinputlayout_email.setErrorEnabled(false); } //邮箱输入框清空后,颜色恢复默认 if (TextUtils.isEmpty(et_email.getText().toString().trim())) { textinputlayout_email.setErrorEnabled(false); } if (charSequence.toString().length() < 1) { textinputlayout_email.setErrorEnabled(false); } } @Override public void afterTextChanged(Editable editable) { } }); et_email.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (!hasFocus) { if (!isValidEmail(et_email.getText())) { // et_email.setError("Email is invalid"); // textInputLayout2.setError("Email is invalid"); } else { // textInputLayout2.setError(null); } } } }); et_code.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { // if (!RegexUtils.isEmail(charSequence)) { // textInputLayout.setError("邮箱格式错误"); // textInputLayout.setErrorEnabled(true); // } else { // textInputLayout.setErrorEnabled(false); // } if (!isValidEmail(et_code.getText())) { // edittext2.setError("Email is invalid"); et_code.setError("Email is invalid"); textinputlayout_code.setError("邮箱格式错误"); textinputlayout_code.setErrorEnabled(true); } else { textinputlayout_code.setError(null); textinputlayout_code.setErrorEnabled(false); } //邮箱输入框清空后,颜色恢复默认 if (TextUtils.isEmpty(et_code.getText().toString().trim())) { textinputlayout_code.setErrorEnabled(false); } if (charSequence.toString().length() < 1) { textinputlayout_code.setErrorEnabled(false); } } @Override public void afterTextChanged(Editable editable) { } }); et_code.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (!hasFocus) { if (!isValidEmail(et_code.getText())) { // et_email.setError("Email is invalid"); // textInputLayout2.setError("Email is invalid"); } else { // textInputLayout2.setError(null); } } } }); } public static boolean isValidEmail(CharSequence target) { return !TextUtils.isEmpty(target) && android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches(); } // 介绍: // app:counterEnabled="true" //设置为true才能显字符数 // app:counterMaxLength="5" //设置最大字符数为5 // app:counterOverflowTextAppearance="@style/HintError" //设置超出字符数后提示文字的颜色,如果不设置默认为@color/colorAccent的颜色 // android:layout_height="wrap_content"> }四.登录样式4: 1.主函数代码: import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.content.Intent; import android.view.View; import android.view.animation.AccelerateDecelerateInterpolator; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.LinearLayout; import androidx.annotation.Nullable; import com.hjq.demo.R; import com.hjq.demo.common.MyActivity; import com.hjq.demo.helper.InputTextHelper; import com.hjq.demo.other.IntentKey; import com.hjq.demo.other.KeyboardWatcher; import com.hjq.demo.wxapi.WXEntryActivity; import com.hjq.image.ImageLoader; import com.hjq.umeng.Platform; import com.hjq.umeng.UmengClient; import com.hjq.umeng.UmengLogin; import butterknife.BindView; import butterknife.OnClick; /** * 登录界面 */ public final class LoginActivity extends MyActivity implements UmengLogin.OnLoginListener, KeyboardWatcher.SoftKeyboardStateListener { @BindView(R.id.iv_login_logo) ImageView mLogoView; @BindView(R.id.ll_login_body) LinearLayout mBodyLayout; @BindView(R.id.et_login_phone) EditText mPhoneView; @BindView(R.id.et_login_password) EditText mPasswordView; @BindView(R.id.btn_login_commit) Button mCommitView; @BindView(R.id.v_login_blank) View mBlankView; @BindView(R.id.ll_login_other) View mOtherView; @BindView(R.id.iv_login_qq) View mQQView; @BindView(R.id.iv_login_wx) View mWeChatView; /** logo 缩放比例 */ private final float mLogoScale = 0.8f; /** 动画时间 */ private final int mAnimTime = 300; @Override protected int getLayoutId() { return R.layout.activity_login; } @Override protected void initView() { InputTextHelper.with(this) .addView(mPhoneView) .addView(mPasswordView) .setMain(mCommitView) .setListener(new InputTextHelper.OnInputTextListener() { @Override public boolean onInputChange(InputTextHelper helper) { return mPhoneView.getText().toString().length() == 11 && mPasswordView.getText().toString().length() >= 6; } }) .build(); post(new Runnable() { @Override public void run() { // 因为在小屏幕手机上面,因为计算规则的因素会导致动画效果特别夸张,所以不在小屏幕手机上面展示这个动画效果 if (mBlankView.getHeight() > mBodyLayout.getHeight()) { // 只有空白区域的高度大于登录框区域的高度才展示动画 KeyboardWatcher.with(LoginActivity.this) .setListener(LoginActivity.this); } } }); } @Override protected void initData() { // 判断用户当前有没有安装 QQ if (!UmengClient.isAppInstalled(this, Platform.QQ)) { mQQView.setVisibility(View.GONE); } // 判断用户当前有没有安装微信 if (!UmengClient.isAppInstalled(this, Platform.WECHAT)) { mWeChatView.setVisibility(View.GONE); } // 如果这两个都没有安装就隐藏提示 if (mQQView.getVisibility() == View.GONE && mWeChatView.getVisibility() == View.GONE) { mOtherView.setVisibility(View.GONE); } } @Override public void onRightClick(View v) { // 跳转到注册界面 startActivityForResult(RegisterActivity.class, new ActivityCallback() { @Override public void onActivityResult(int resultCode, @Nullable Intent data) { // 如果已经注册成功,就执行登录操作 if (resultCode == RESULT_OK && data != null) { mPhoneView.setText(data.getStringExtra(IntentKey.PHONE)); mPasswordView.setText(data.getStringExtra(IntentKey.PASSWORD)); onClick(mCommitView); } } }); } @OnClick({R.id.tv_login_forget, R.id.btn_login_commit, R.id.iv_login_qq, R.id.iv_login_wx}) public void onClick(View v) { switch (v.getId()) { case R.id.tv_login_forget: startActivity(PasswordForgetActivity.class); break; case R.id.btn_login_commit: if (mPhoneView.getText().toString().length() != 11) { toast(R.string.common_phone_input_error); } else { showLoading(); postDelayed(new Runnable() { @Override public void run() { showComplete(); // 处理登录 startActivityFinish(HomeActivity.class); } }, 2000); } break; case R.id.iv_login_qq: case R.id.iv_login_wx: toast("记得改好第三方 AppID 和 AppKey,否则会调不起来哦"); Platform platform; switch (v.getId()) { case R.id.iv_login_qq: platform = Platform.QQ; break; case R.id.iv_login_wx: platform = Platform.WECHAT; toast("也别忘了改微信 " + WXEntryActivity.class.getSimpleName() + " 类所在的包名哦"); break; default: throw new IllegalStateException("are you ok?"); } UmengClient.login(this, platform, this); break; default: break; } } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); // 友盟登录回调 UmengClient.onActivityResult(this, requestCode, resultCode, data); } /** * 友盟第三方登录授权回调接口 * {@link UmengLogin.OnLoginListener} */ /** * 授权成功的回调 * * @param platform 平台名称 * @param data 用户资料返回 */ @Override public void onSucceed(Platform platform, UmengLogin.LoginData data) { // 判断第三方登录的平台 switch (platform) { case QQ: break; case WECHAT: break; default: break; } ImageLoader.with(this) .load(data.getIcon()) .circle() .into(mLogoView); toast("昵称:" + data.getName() + "\n" + "性别:" + data.getSex()); toast("id:" + data.getId()); toast("token:" + data.getToken()); } /** * 授权失败的回调 * * @param platform 平台名称 * @param t 错误原因 */ @Override public void onError(Platform platform, Throwable t) { toast("第三方登录出错:" + t.getMessage()); } /** * 授权取消的回调 * * @param platform 平台名称 */ @Override public void onCancel(Platform platform) { toast("取消第三方登录"); } /** * {@link KeyboardWatcher.SoftKeyboardStateListener} */ @Override public void onSoftKeyboardOpened(int keyboardHeight) { int screenHeight = getResources().getDisplayMetrics().heightPixels; int[] location = new int[2]; // 获取这个 View 在屏幕中的坐标(左上角) mBodyLayout.getLocationOnScreen(location); //int x = location[0]; int y = location[1]; int bottom = screenHeight - (y + mBodyLayout.getHeight()); if (keyboardHeight > bottom){ // 执行位移动画 ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(mBodyLayout, "translationY", 0, -(keyboardHeight - bottom)); objectAnimator.setDuration(mAnimTime); objectAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); objectAnimator.start(); // 执行缩小动画 mLogoView.setPivotX(mLogoView.getWidth() / 2f); mLogoView.setPivotY(mLogoView.getHeight()); AnimatorSet animatorSet = new AnimatorSet(); ObjectAnimator scaleX = ObjectAnimator.ofFloat(mLogoView, "scaleX", 1.0f, mLogoScale); ObjectAnimator scaleY = ObjectAnimator.ofFloat(mLogoView, "scaleY", 1.0f, mLogoScale); ObjectAnimator translationY = ObjectAnimator.ofFloat(mLogoView, "translationY", 0.0f, -(keyboardHeight - bottom)); animatorSet.play(translationY).with(scaleX).with(scaleY); animatorSet.setDuration(mAnimTime); animatorSet.start(); } } @Override public void onSoftKeyboardClosed() { // 执行位移动画 ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(mBodyLayout, "translationY", mBodyLayout.getTranslationY(), 0); objectAnimator.setDuration(mAnimTime); objectAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); objectAnimator.start(); if (mLogoView.getTranslationY() == 0){ return; } // 执行放大动画 mLogoView.setPivotX(mLogoView.getWidth() / 2f); mLogoView.setPivotY(mLogoView.getHeight()); AnimatorSet animatorSet = new AnimatorSet(); ObjectAnimator scaleX = ObjectAnimator.ofFloat(mLogoView, "scaleX", mLogoScale, 1.0f); ObjectAnimator scaleY = ObjectAnimator.ofFloat(mLogoView, "scaleY", mLogoScale, 1.0f); ObjectAnimator translationY = ObjectAnimator.ofFloat(mLogoView, "translationY", mLogoView.getTranslationY(), 0); animatorSet.play(translationY).with(scaleX).with(scaleY); animatorSet.setDuration(mAnimTime); animatorSet.start(); } }package com.hjq.demo.other; import android.app.Activity; import android.app.Application; import android.graphics.Rect; import android.os.Build; import android.os.Bundle; import android.view.View; import android.view.ViewTreeObserver; import android.view.Window; import android.view.WindowManager; /** 软键盘监听类 */ public final class KeyboardWatcher implements ViewTreeObserver.OnGlobalLayoutListener, Application.ActivityLifecycleCallbacks { private Activity mActivity; private View mContentView; private SoftKeyboardStateListener mListeners; private boolean isSoftKeyboardOpened; private int mStatusBarHeight; public static KeyboardWatcher with(Activity activity) { return new KeyboardWatcher(activity); } private KeyboardWatcher(Activity activity) { mActivity = activity; mContentView = activity.findViewById(Window.ID_ANDROID_CONTENT); mActivity.getApplication().registerActivityLifecycleCallbacks(this); mContentView.getViewTreeObserver().addOnGlobalLayoutListener(this); // 获取 status_bar_height 资源的 ID int resourceId = mActivity.getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { //根据资源 ID 获取响应的尺寸值 mStatusBarHeight = mActivity.getResources().getDimensionPixelSize(resourceId); } } /** * {@link ViewTreeObserver.OnGlobalLayoutListener} */ @Override public void onGlobalLayout() { final Rect r = new Rect(); //r will be populated with the coordinates of your view that area still visible. mContentView.getWindowVisibleDisplayFrame(r); final int heightDiff = mContentView.getRootView().getHeight() - (r.bottom - r.top); if (!isSoftKeyboardOpened && heightDiff > mContentView.getRootView().getHeight() / 4) { isSoftKeyboardOpened = true; if ((mActivity.getWindow().getAttributes().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != WindowManager.LayoutParams.FLAG_FULLSCREEN) { if (mListeners != null) { mListeners.onSoftKeyboardOpened(heightDiff - mStatusBarHeight); } } else { if (mListeners != null) { mListeners.onSoftKeyboardOpened(heightDiff); } } } else if (isSoftKeyboardOpened && heightDiff < mContentView.getRootView().getHeight() / 4) { isSoftKeyboardOpened = false; if (mListeners != null) { mListeners.onSoftKeyboardClosed(); } } } /** * 设置软键盘弹出监听 */ public void setListener(SoftKeyboardStateListener listener) { mListeners = listener; } /** * {@link Application.ActivityLifecycleCallbacks} */ @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { } @Override public void onActivityStarted(Activity activity) { } @Override public void onActivityResumed(Activity activity) { } @Override public void onActivityPaused(Activity activity) { } @Override public void onActivityStopped(Activity activity) { } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { } @Override public void onActivityDestroyed(Activity activity) { if (mActivity == activity) { mActivity.getApplication().unregisterActivityLifecycleCallbacks(this); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { mContentView.getViewTreeObserver().removeOnGlobalLayoutListener(this); } mActivity = null; mContentView = null; mListeners = null; } } /** * 软键盘状态监听器 */ public interface SoftKeyboardStateListener { /** * 软键盘弹出了 * @param keyboardHeight 软键盘高度 */ void onSoftKeyboardOpened(int keyboardHeight); /** * 软键盘收起了 */ void onSoftKeyboardClosed(); } }
layout_animation_from_bottom.xml @null 15sp #A4A4A4 #333333 10dp 10dp 10dp 10dp match_parent @dimen/line_size @color/colorLine15dp 15dp 8dp 8dp 14sp @color/white90 center @drawable/selector_button @null selector_button.xml 五.登录之重置密码: 1.主函数代码: import android.view.View; import android.widget.Button; import android.widget.EditText; import com.hjq.demo.R; import com.hjq.demo.common.MyActivity; import com.hjq.demo.helper.InputTextHelper; import butterknife.BindView; import butterknife.OnClick; /** * 重置密码 */ public final class PasswordResetActivity extends MyActivity { @BindView(R.id.et_password_reset_password1) EditText mPasswordView1; @BindView(R.id.et_password_reset_password2) EditText mPasswordView2; @BindView(R.id.btn_password_reset_commit) Button mCommitView; @Override protected int getLayoutId() { return R.layout.activity_password_reset; } @Override protected void initView() { InputTextHelper.with(this) .addView(mPasswordView1) .addView(mPasswordView2) .setMain(mCommitView) .setListener(new InputTextHelper.OnInputTextListener() { @Override public boolean onInputChange(InputTextHelper helper) { return mPasswordView1.getText().toString().length() >= 6 && mPasswordView1.getText().toString().equals(mPasswordView2.getText().toString()); } }) .build(); } @Override protected void initData() { } @OnClick({R.id.btn_password_reset_commit}) public void onClick(View v) { switch (v.getId()) { case R.id.btn_password_reset_commit: toast(R.string.password_reset_success); finish(); break; default: break; } } }2.布局:
https://github.com/qingmei2/Samples-Android 请忽略下面的笔记: /** * 自定义绚丽的ProgressBar. */ public class ProgressBarView1 extends View { /** * 进度条所占用的角度 */ private static final int ARC_FULL_DEGREE = 300; /** * 弧线的宽度 */ private int STROKE_WIDTH; /** * 组件的宽,高 */ private int width, height; /** * 进度条最大值和当前进度值 */ private float max, progress; /** * 是否允许拖动进度条 */ private boolean draggingEnabled = false; /** * 绘制弧线的矩形区域 */ private RectF circleRectF; /** * 绘制弧线的画笔 */ private Paint progressPaint; /** * 绘制文字的画笔 */ private Paint textPaint; /** * 绘制当前进度值的画笔 */ private Paint thumbPaint; /** * 圆弧的半径 */ private int circleRadius; /** * 圆弧圆心位置 */ private int centerX, centerY; public ProgressBarView1(Context context) { super(context); init(); } public ProgressBarView1(Context context, AttributeSet attrs) { super(context, attrs); init(); } public ProgressBarView1(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { progressPaint = new Paint(); progressPaint.setAntiAlias(true); textPaint = new Paint(); textPaint.setColor(Color.WHITE); textPaint.setAntiAlias(true); thumbPaint = new Paint(); thumbPaint.setAntiAlias(true); //使用自定义字体 textPaint.setTypeface(Typeface.createFromAsset(getContext().getAssets(), "fangz.ttf")); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (width == 0 || height == 0) { width = getWidth(); height = getHeight(); //计算圆弧半径和圆心点 circleRadius = Math.min(width, height) / 2; STROKE_WIDTH = circleRadius / 12; circleRadius -= STROKE_WIDTH; centerX = width / 2; centerY = height / 2; //圆弧所在矩形区域 circleRectF = new RectF(); circleRectF.left = centerX - circleRadius; circleRectF.top = centerY - circleRadius; circleRectF.right = centerX + circleRadius; circleRectF.bottom = centerY + circleRadius; } } private Rect textBounds = new Rect(); @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); float start = 90 + ((360 - ARC_FULL_DEGREE) >> 1); //进度条起始点 float sweep1 = ARC_FULL_DEGREE * (progress / max); //进度划过的角度 float sweep2 = ARC_FULL_DEGREE - sweep1; //剩余的角度 //绘制起始位置小圆形 progressPaint.setColor(Color.WHITE); progressPaint.setStrokeWidth(0); progressPaint.setStyle(Paint.Style.FILL); float radians = (float) (((360.0f - ARC_FULL_DEGREE) / 2) / 180 * Math.PI); float startX = centerX - circleRadius * (float) Math.sin(radians); float startY = centerY + circleRadius * (float) Math.cos(radians); canvas.drawCircle(startX, startY, STROKE_WIDTH / 2, progressPaint); //绘制进度条 progressPaint.setStrokeWidth(STROKE_WIDTH); progressPaint.setStyle(Paint.Style.STROKE);//设置空心 canvas.drawArc(circleRectF, start, sweep1, false, progressPaint); //绘制进度条背景 progressPaint.setColor(Color.parseColor("#d64444")); canvas.drawArc(circleRectF, start + sweep1, sweep2, false, progressPaint); //绘制结束位置小圆形 progressPaint.setStrokeWidth(0); progressPaint.setStyle(Paint.Style.FILL); float endX = centerX + circleRadius * (float) Math.sin(radians); float endY = centerY + circleRadius * (float) Math.cos(radians); canvas.drawCircle(endX, endY, STROKE_WIDTH / 2, progressPaint); //上一行文字 textPaint.setTextSize(circleRadius >> 1); String text = (int) (100 * progress / max) + ""; float textLen = textPainasureText(text); //计算文字高度 textPaint.getTextBounds("8", 0, 1, textBounds); float h1 = textBounds.height(); //% 前面的数字水平居中,适当调整 float extra = text.startsWith("1") ? -textPainasureText("1") / 2 : 0; canvas.drawText(text, centerX - textLen / 2 + extra, centerY - 30 + h1 / 2, textPaint); //百分号 textPaint.setTextSize(circleRadius >> 2); canvas.drawText("%", centerX + textLen / 2 + extra + 5, centerY - 30 + h1 / 2, textPaint); //下一行文字 textPaint.setTextSize(circleRadius / 5); text = "可用内存充足"; textLen = textPainasureText(text); textPaint.getTextBounds(text, 0, text.length(), textBounds); float h2 = textBounds.height(); canvas.drawText(text, centerX - textLen / 2, centerY + h1 / 2 + h2, textPaint); //绘制进度位置,也可以直接替换成一张图片 float progressRadians = (float) (((360.0f - ARC_FULL_DEGREE) / 2 + sweep1) / 180 * Math.PI); float thumbX = centerX - circleRadius * (float) Math.sin(progressRadians); float thumbY = centerY + circleRadius * (float) Math.cos(progressRadians); thumbPaint.setColor(Color.parseColor("#33d64444")); canvas.drawCircle(thumbX, thumbY, STROKE_WIDTH * 2.0f, thumbPaint); thumbPaint.setColor(Color.parseColor("#99d64444")); canvas.drawCircle(thumbX, thumbY, STROKE_WIDTH * 1.4f, thumbPaint); thumbPaint.setColor(Color.WHITE); canvas.drawCircle(thumbX, thumbY, STROKE_WIDTH * 0.8f, thumbPaint); } private boolean isDragging = false; @Override public boolean onTouchEvent(@NonNull MotionEvent event) { if (!draggingEnabled) { return super.onTouchEvent(event); } //处理拖动事件 float currentX = event.getX(); float currentY = event.getY(); int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: //判断是否在进度条thumb位置 if (checkOnArc(currentX, currentY)) { float newProgress = calDegreeByPosition(currentX, currentY) / ARC_FULL_DEGREE * max; setProgressSync(newProgress); isDragging = true; } break; case MotionEvent.ACTION_MOVE: if (isDragging) { //判断拖动时是否移出去了 if (checkOnArc(currentX, currentY)) { setProgressSync(calDegreeByPosition(currentX, currentY) / ARC_FULL_DEGREE * max); } else { isDragging = false; } } break; case MotionEvent.ACTION_UP: isDragging = false; break; } return true; } private float calDistance(float x1, float y1, float x2, float y2) { return (float) Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); } /** * 判断该点是否在弧线上(附近) */ private boolean checkOnArc(float currentX, float currentY) { float distance = calDistance(currentX, currentY, centerX, centerY); float degree = calDegreeByPosition(currentX, currentY); return distance > circleRadius - STROKE_WIDTH * 5 && distance < circleRadius + STROKE_WIDTH * 5 && (degree >= -8 && degree centerY && currentX > centerX) { a1 += 360; } return a1 - (360 - ARC_FULL_DEGREE) / 2; } public void setMax(int max) { this.max = max; invalidate(); } public void setProgress(float progress) { final float validProgress = checkProgress(progress); //动画切换进度值 new Thread(new Runnable() { @Override public void run() { float oldProgress = ProgressBarView1.this.progress; for (int i = 1; i max ? max : progress; } public void setDraggingEnabled(boolean draggingEnabled) { this.draggingEnabled = draggingEnabled; } }
|
CopyRight 2018-2019 实验室设备网 版权所有 |