Adnroid 自定义ProgressDialog加载中(加载圈)

yizhihongxing

Android 自定义ProgressDialog加载中(加载圈)攻略

在 Android 开发中,我们常常需要向用户展示加载中的提示,在这种场景下,使用 ProgressDialog 是非常常见的方式。但是,android 自带的 ProgressDialog 的样式有限,无法满足一些特殊的需求。本文将会介绍如何自定义 ProgressDialog,以实现更为灵活的加载中提示。

1. 使用自定义布局实现自定义ProgressDialog

1.1 编写布局文件

首先需要准备一个用于自定义 ProgressDialog 的布局文件。该布局文件可以使用 ProgressBar 来实现加载圈的效果,同时还可以添加一些文字说明等内容以更加清晰地告诉用户当前的状态。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center">

    <ProgressBar
        android:id="@+id/progressBar"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_centerInParent="true" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/progressBar"
        android:text="Loading..."
        android:layout_centerHorizontal="true"
        android:textSize="16sp"/>

</RelativeLayout>

1.2 使用自定义布局实现ProgressDialog

接下来,在需要使用 ProgressDialog 的地方,我们就可以通过 LayoutInflater 来加载我们刚才准备好的布局文件,并将其设置到自定义的 ProgressDialog 中。

public class MyProgressDialog extends Dialog {
    private ProgressBar mProgressBar;
    private TextView mTextView;

    public MyProgressDialog(Context context) {
        super(context, R.style.MyProgressDialog);
        setContentView(R.layout.layout_my_progress_dialog);
        mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
        mTextView = (TextView) findViewById(R.id.textView);
    }

    /**
     * 设置加载中文字
     * 
     * @param message 加载中文字内容
     */
    public void setMessage(String message) {
        mTextView.setText(message);
    }
}

接下来就可以在需要的地方使用自定义的 ProgressDialog 了,例如:

MyProgressDialog dialog = new MyProgressDialog(this);
dialog.setMessage("正在加载,请稍候...");
dialog.show();

2. 自定义ProgressDialog之CircleProgressView

2.1 CircleProgressView 的设计思路

使用自定义布局的方式实现自定义 ProgressDialog,虽然灵活性较高,但需要手动实现加载圈的绘制,较为复杂。在这里,我们推荐另一种实现方式:使用自定义 View 来实现加载圈的绘制。这种方式的好处是我们可以更方便、更灵活地设计出不同风格的加载圈。接下来,我们将实现一个 CircleProgressView 的自定义 View。这个 CircleProgressView 是由一个圆环和一个指针组成的,进度的变化将会导致指针的旋转。

2.2 CircleProgressView 的实现步骤

首先,我们需要实现自定义 View 的基本功能,包括构造函数、测量、布局和绘制等。然后,根据需求增加进度值设置的接口和进度值变化时指针旋转的逻辑。

① 自定义 View 的构造方法

public CircleProgressView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context);
}

private void init(Context context) {
    // 获取自定义属性(圆环颜色和宽度,指针颜色和长度)
    TypedArray ta = context.obtainStyledAttributes(R.styleable.CircleProgressView);
    mRingColor = ta.getColor(R.styleable.CircleProgressView_ringColor, Color.parseColor("#e0e0e0"));
    mRingWidth = ta.getDimensionPixelSize(R.styleable.CircleProgressView_ringWidth, Utils.dp2px(context, 3));
    mPointerColor = ta.getColor(R.styleable.CircleProgressView_pointerColor, Color.WHITE);
    mPointerLength = ta.getDimensionPixelSize(R.styleable.CircleProgressView_pointerLength, Utils.dp2px(context, 22));
    ta.recycle();

    // 初始化画笔
    mRingPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mRingPaint.setStyle(Paint.Style.STROKE);
    mRingPaint.setStrokeWidth(mRingWidth);
    mRingPaint.setColor(mRingColor);

    // 初始化旋转动画
    mRotateAnim = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
    mRotateAnim.setInterpolator(new LinearInterpolator());
    mRotateAnim.setDuration(1000);
    mRotateAnim.setRepeatCount(Animation.INFINITE);
    mRotateAnim.setRepeatMode(Animation.RESTART);
    mRotateAnim.setInterpolator(new LinearInterpolator());
}

② 重写 onMeasure() 方法

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

    int width, height;

    if (widthMode == MeasureSpec.EXACTLY) {
        width = widthSize;
    } else {
        width = mPointerLength * 2 + mRingWidth + getPaddingLeft() + getPaddingRight();
    }

    if (heightMode == MeasureSpec.EXACTLY) {
        height = heightSize;
    } else {
        height = mPointerLength * 2 + mRingWidth + getPaddingTop() + getPaddingBottom();
    }

    setMeasuredDimension(width, height);
}

③ 重写 onDraw() 方法

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    int centerX = getWidth() / 2;
    int centerY = getHeight() / 2;
    int pointerX = centerX + (int) (mPointerLength * Math.cos(Math.toRadians(mProgress * 3.6 - 90)));
    int pointerY = centerY + (int) (mPointerLength * Math.sin(Math.toRadians(mProgress * 3.6 - 90)));

    canvas.drawCircle(centerX, centerY, getWidth() / 2 - mRingWidth / 2, mRingPaint);

    mPointerPaint.setColor(mPointerColor);
    mPointerPaint.setStrokeWidth(Utils.dp2px(getContext(), 3));
    mPointerPaint.setStyle(Paint.Style.FILL);
    canvas.drawLine(centerX, centerY, pointerX, pointerY, mPointerPaint);
}

④ 实现进度变化与指针旋转的逻辑

/**
 * 设置进度值
 *
 * @param progress 进度值(0-100)
 */
public void setProgress(int progress) {
    mProgress = progress;
    invalidate();
}

/**
 * 开始旋转动画
 */
public void startAnimate() {
    clearAnimation();
    startAnimation(mRotateAnim);
}

/**
 * 停止旋转动画
 */
public void stopAnimate() {
    clearAnimation();
}

2.3 在布局文件中使用 CircleProgressView

使用 CircleProgressView 的方式与使用普通 View 无异,只需将 CircleProgressView 添加到布局文件的相应位置即可。

<com.example.mylibrary.widget.CircleProgressView
    android:id="@+id/progressView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    app:pointerColor="#ff0000"
    app:pointerLength="30dp"
    app:ringColor="#e0e0e0"
    app:ringWidth="4dp" />

2.4 在代码中使用 CircleProgressView

和普通 View 一样,可以在代码中通过 findViewById 来获取 CircleProgressView 实例,并调用相应的方法来动态修改进度值和指针的样式。

CircleProgressView progressView = findViewById(R.id.progressView);
progressView.setProgress(50);
progressView.startAnimate();

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Adnroid 自定义ProgressDialog加载中(加载圈) - Python技术站

(0)
上一篇 2023年6月25日
下一篇 2023年6月25日

相关文章

  • Java单链表基本操作的实现

    Java单链表基本操作的实现 单链表是一种常见的线性数据结构,由多个节点(Node)构成。每个节点包含了一个数据(Data)域和一个指向下一个节点的指针(Next)。单链表的基本操作包括:插入,删除,查找和遍历。下面将对这些操作进行详细讲解。 定义节点类 定义一个节点类,包含数据域和下一个节点的指针。如下所示: public class Node { pub…

    other 2023年6月27日
    00
  • Android自定义view仿IOS开关效果

    下面我将为您详细讲解“Android自定义view仿IOS开关效果”的完整攻略。 简介 本文将介绍如何实现一个仿IOS开关的自定义View,当然,这种开关在Android中早已有其它的替代品,但是通过手动编写开关的代码,了解自定义View的知识,在此基础上进行风格的定制以及不同需求的实现,这是值得一学的。 实现思路 开关主要由背景圆角矩形、白色小球、阴影三部…

    other 2023年6月27日
    00
  • Java 线程的生命周期完整实例分析

    Java 线程的生命周期完整实例分析 在 Java 中,线程是非常常见的概念。了解线程的生命周期对于正确编写多线程程序是非常重要的。本文将介绍 Java 线程的完整生命周期,并给出两个实例进行说明。 Java 线程的生命周期 Java 线程的生命周期可以归纳为以下 6 个阶段: 新建(New):当线程对象被创建后处于新建状态。 就绪(Runnable):当调…

    other 2023年6月27日
    00
  • Java web入门指南之在Idea上创建Java web项目

    Java Web入门指南之在Idea上创建Java Web项目 本攻略将详细介绍如何在Idea上创建Java Web项目。Java Web项目是基于Java技术的Web应用程序,可以通过浏览器访问。以下是创建Java Web项目的步骤: 步骤一:安装Idea 首先,确保已经安装了最新版本的Idea集成开发环境。可以从Idea官方网站(https://www.…

    other 2023年8月6日
    00
  • 详解aws免费服务器申请及网络代理搭建教程

    标题:详解AWS免费服务器申请及网络代理搭建教程 申请AWS免费服务器 首先创建AWS账号并登录AWS控制台,网址为:https://aws.amazon.com/cn/ 进入控制台后,选择“EC2”,在“EC2”页面中,可以看到“启动实例”按钮。点击该按钮开始创建免费服务器实例。 在“启动实例”页面中,选择“Amazon Linux 2 AMI (HVM)…

    other 2023年6月27日
    00
  • Linux之操作文件的系统调用

    接下来我将详细讲解“Linux之操作文件的系统调用”的完整攻略。 系统调用 系统调用(System Call)是指操作系统提供的应用程序与操作系统之间进行交互的接口,为应用程序提供操作系统服务。Linux操作系统中提供了丰富的系统调用,其中包括操作文件的系统调用。 操作文件的系统调用 Linux操作文件的系统调用主要包括以下几类: 打开/关闭文件:open,…

    other 2023年6月27日
    00
  • Linux 通过Rsync+Inotify实现本、异地远程数据实时同步功能

    Linux 通过Rsync+Inotify实现本、异地远程数据实时同步功能攻略 实时同步本、异地数据是现代社会普遍需求,Linux平台上通过Rsync+Inotify技术实现本、异地远程数据实时同步功能非常方便。 环境准备 在使用Rsync+Inotify实现本、异地远程数据实时同步功能之前,需要进行环境配置。 1. 安装Rsync 在Debian/Ubun…

    other 2023年6月26日
    00
  • pdf转base64

    pdf转base64 在现代的网络应用中,我们经常需要在浏览器中显示或传输文件。而在某些情况下,我们希望能够将这些文件以一种可靠的方式编码并传输,这时候就需要用到base64编码。 而在传输文件时,常常需要将文件转换为base64格式,然后再将其嵌入到HTML、JSON等数据格式中。本文将重点介绍如何将PDF文件转换成base64格式。 base64简介 b…

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部