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

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日

相关文章

  • R语言中文社区历史文章整理(类型篇)

    R语言中文社区历史文章整理(类型篇) R语言是一种功能强大的统计分析软件,已经在学术界和工业界广泛应用。在R语言中文社区中,有许多优秀的文章涉及了众多功能和应用场景,并且这些文章被整理成了不同类型。本篇文章将会详细介绍R语言中文社区历史文章整理的类型和其涵盖的主题。 数据处理类文章 数据处理类文章是R语言中文社区中最为常见的文章类型之一。这些文章通常涵盖了数…

    其他 2023年3月28日
    00
  • spring容器初始化遇到的死锁问题解决

    spring容器初始化时遇到的死锁问题可能是由于多线程同时初始化一些对象所致。以下是解决死锁问题的攻略: 一、使用Java线程分析工具发现死锁1. 使用Java线程分析工具(如jstack、jconsole、jvisualvm)来查找死锁线程。2. 分析死锁线程,找出死锁的原因。3. 解决死锁问题。 二、避免上下文加载和初始化时的死锁1. 保证Spring上…

    other 2023年6月20日
    00
  • 用Java代码实现栈数据结构的基本方法归纳

    下面我来详细讲解用Java代码实现栈数据结构的基本方法归纳的完整攻略。 栈数据结构 栈是一种基本的数据结构,其遵循先进后出(Last In First Out, LIFO)的原则,类比于我们平常在餐馆里取餐时,总是取最后一个放进去的餐盘。 栈的常见操作包括压栈(push)、弹栈(pop)、获取栈顶元素(peek)等。 用Java代码实现栈数据结构 方式一:使…

    other 2023年6月27日
    00
  • coreldraw(cdr)2018安装教程详解

    CorelDRAW 2018安装教程详解 1. 检查系统要求 在安装 CorelDRAW 2018 之前,需要先检查系统是否符合最低系统要求。以下是 CorelDRAW 2018 的最低系统要求: 操作系统:Windows 7 SP1、Windows 8.1 或 Windows 10,32 位或 64 位版本; 处理器:Intel Core i3/5/7 或…

    其他 2023年4月16日
    00
  • ASP.NET控件之RadioButtonList详解

    ASP.NET控件之RadioButtonList详解 简介 RadioButtonList是ASP.NET Web Forms中的一个常用控件,它用于显示一组互斥的选项,用户只能选择其中的一个选项。RadioButtonList可以与多个ListItem集合一起使用,每个ListItem表示一个选项。 使用方式 使用RadioButtonList非常简单,…

    other 2023年6月27日
    00
  • 此工作簿已丢失VBA项目,ACTIVEX控件以及其它任何与可编程序相关的功能

    这个报错通常发生在使用带有宏、ActiveX控件或其他可编程功能的Excel文件中,可能是由于文件本身被不正确地保存或复制而导致的。当打开这种文件时,Excel会显示一个提示框,告诉用户文件失去了相应的功能。 这个问题的解决方法是通过编辑文件的VBA代码、重新插入ActiveX控件或修复文件。下面给出一些具体的方法: 1. 通过编辑VBA代码解决报错 步骤:…

    other 2023年6月26日
    00
  • IP地址组成与类型

    IP地址组成与类型 IP地址是互联网中用于标识和定位设备的一种地址。它由一系列数字组成,用于唯一地标识网络中的每个设备。IP地址由两个主要部分组成:网络地址和主机地址。 IP地址的组成 IP地址由32位二进制数表示,通常以四个十进制数(每个数范围从0到255)的形式呈现,用点分隔。例如,192.168.0.1是一个常见的IP地址。 IP地址的32位二进制数可…

    other 2023年7月29日
    00
  • 流放之路3.2暴徒野蛮人先祖战士长BD介绍 低价高伤害BD攻略

    流放之路3.2暴徒野蛮人先祖战士长BD介绍 低价高伤害BD攻略 简介 本攻略介绍了流放之路3.2版本中,暴徒野蛮人先祖战士长(Berserker Ancestral Warchief)职业的低价高伤害BD(Build)攻略。该BD以低投资为前提,通过战士长技能和暴徒的优势,实现高伤害输出。 技能树和天赋 技能树: 大区域:选择与先祖战士长技能相关的天赋点位,…

    other 2023年6月28日
    00
合作推广
合作推广
分享本页
返回顶部