自定义Loading Dialog,图片(仿美团)、GIF图片加载两种方式

原创 2016年05月12日 13:31:10

整理了一下网上的 Loading Dialog,
一个仿造美团的,还有一个是直接加载gif动态图片的。
MainActivity.java

import android.app.Activity;
import android.os.Bundle;
import android.view.View;

import com.example.loading.R;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);
    }
    /**
     * 显示美团进度对话框
     * @param v
     */
    public void showmeidialog(View v){
        LoadingDialog dialog =new LoadingDialog(this, "正在加载中",R.anim.frame, LoadingDialog.Type_IMG);
        dialog.show();
    }

    public void showGifdialog(View v){
        LoadingDialog dialog =new LoadingDialog(this, "",R.raw.kitty, LoadingDialog.Type_GIF);
        dialog.show();
    }
}

LoadingDialog.java

import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.example.loading.R;

/**
 * 自定义Loading对话框
 */
public class LoadingDialog extends ProgressDialog {

    private AnimationDrawable mAnimation;
    private Context mContext;
    // 显示的图片
    private ImageView mImageView;
    // 提示的文字
    private String mLoadingTip;
    private TextView mLoadingTv;
    private int mResid;
    private LinearLayout load_layout;
    // GIF动态图片
    private GifView load_gifv;
    // 加载框显示类型
    private String showType;

    public static final String Type_GIF = "GIF";
    public static final String Type_IMG = "IMG";

    /**
     * loading对话框构造方法
     * 
     * @param context
     *            上下文
     * @param content
     *            提示信息
     * @param resId
     *            资源
     * @param type
     *            loading图类型 GIF;IMG
     */
    public LoadingDialog(Context context, String content, int resId, String type) {
        super(context);
        this.mContext = context;
        this.mLoadingTip = content;
        this.mResid = resId;
        this.showType = type;
        setCanceledOnTouchOutside(true);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.loading_dialog);
        initView();
        initData();
    }

    /**
     * 页面初始化
     */
    private void initView() {
        mLoadingTv = (TextView) findViewById(R.id.load_tetv);
        mImageView = (ImageView) findViewById(R.id.load_imgv);
        load_layout = (LinearLayout) findViewById(R.id.load_layout);
        load_gifv = (GifView) findViewById(R.id.load_gifv);
    }

    /**
     * 数据初始化
     */
    private void initData() {
        if(showType.equals(Type_GIF)){
            load_gifv.setMovieResource(mResid);
            load_gifv.setVisibility(View.VISIBLE);
            load_layout.setVisibility(View.GONE);
        }else if(showType.equals(Type_IMG)){
            load_gifv.setVisibility(View.GONE);
            load_layout.setVisibility(View.VISIBLE);
            mImageView.setBackgroundResource(mResid);
            // 通过ImageView对象拿到背景显示的AnimationDrawable
            mAnimation = (AnimationDrawable) mImageView.getBackground();
            // 为了防止在onCreate方法中只显示第一帧的解决方案之一
            mImageView.post(new Runnable() {
                @Override
                public void run() {
                    mAnimation.start();
                }
            });
            mLoadingTv.setText(mLoadingTip);
        }
    }

    /**
     * 设置提示信息内容
     * 
     * @param str
     */
    public void setContent(String str) {
        mLoadingTv.setText(str);
    }
}

GifView.java

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;

import com.example.loading.R;

/**
 * 加载GIF的自定义View
 *
 */
public class GifView extends View {

    /**
     * 默认为1秒
     */
    private static final int DEFAULT_MOVIE_DURATION = 1000;

    private int mMovieResourceId;

    private Movie mMovie;

    private long mMovieStart;

    private int mCurrentAnimationTime = 0;

    private float mLeft;

    private float mTop;

    private float mScale;

    private int mMeasuredMovieWidth;

    private int mMeasuredMovieHeight;

    private boolean mVisible = true;

    private volatile boolean mPaused = false;

    public GifView(Context context) {
        this(context, null);
    }

    public GifView(Context context, AttributeSet attrs) {
        this(context, attrs, R.styleable.CustomTheme_gifViewStyle);
    }

    public GifView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setViewAttributes(context, attrs, defStyle);
    }

    @SuppressLint("NewApi")
    private void setViewAttributes(Context context, AttributeSet attrs, int defStyle) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        }
        // 从描述文件中读出gif的值,创建出Movie实例
        final TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.GifView, defStyle, R.style.Widget_GifView);
        mMovieResourceId = array.getResourceId(R.styleable.GifView_gif, -1);
        mPaused = array.getBoolean(R.styleable.GifView_paused, false);
        array.recycle();
        if (mMovieResourceId != -1) {
            mMovie = Movie.decodeStream(getResources().openRawResource(mMovieResourceId));
        }
    }

    /**
     * 设置gif图资源
     * 
     * @param movieResId
     */
    public void setMovieResource(int movieResId) {
        this.mMovieResourceId = movieResId;
        mMovie = Movie.decodeStream(getResources().openRawResource(mMovieResourceId));
        requestLayout();
    }

    public void setMovie(Movie movie) {
        this.mMovie = movie;
        requestLayout();
    }

    public Movie getMovie() {
        return mMovie;
    }

    public void setMovieTime(int time) {
        mCurrentAnimationTime = time;
        invalidate();
    }

    /**
     * 设置暂停
     * 
     * @param paused
     */
    public void setPaused(boolean paused) {
        this.mPaused = paused;
        if (!paused) {
            mMovieStart = android.os.SystemClock.uptimeMillis() - mCurrentAnimationTime;
        }
        invalidate();
    }

    /**
     * 判断gif图是否停止了
     * 
     * @return
     */
    public boolean isPaused() {
        return this.mPaused;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (mMovie != null) {
            int movieWidth = mMovie.width();
            int movieHeight = mMovie.height();
            int maximumWidth = MeasureSpec.getSize(widthMeasureSpec);
            float scaleW = (float) movieWidth / (float) maximumWidth;
            mScale = 1f / scaleW;
            mMeasuredMovieWidth = maximumWidth;
            mMeasuredMovieHeight = (int) (movieHeight * mScale);
            setMeasuredDimension(mMeasuredMovieWidth, mMeasuredMovieHeight);
        } else {
            setMeasuredDimension(getSuggestedMinimumWidth(), getSuggestedMinimumHeight());
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        mLeft = (getWidth() - mMeasuredMovieWidth) / 2f;
        mTop = (getHeight() - mMeasuredMovieHeight) / 2f;
        mVisible = getVisibility() == View.VISIBLE;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (mMovie != null) {
            if (!mPaused) {
                updateAnimationTime();
                drawMovieFrame(canvas);
                invalidateView();
            } else {
                drawMovieFrame(canvas);
            }
        }
    }

    @SuppressLint("NewApi")
    private void invalidateView() {
        if (mVisible) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                postInvalidateOnAnimation();
            } else {
                invalidate();
            }
        }
    }

    private void updateAnimationTime() {
        long now = android.os.SystemClock.uptimeMillis();
        // 如果第一帧,记录起始时间
        if (mMovieStart == 0) {
            mMovieStart = now;
        }
        // 取出动画的时长
        int dur = mMovie.duration();
        if (dur == 0) {
            dur = DEFAULT_MOVIE_DURATION;
        }
        // 算出需要显示第几帧
        mCurrentAnimationTime = (int) ((now - mMovieStart) % dur);
    }

    private void drawMovieFrame(Canvas canvas) {
        // 设置要显示的帧,绘制即可
        mMovie.setTime(mCurrentAnimationTime);
        canvas.save(Canvas.MATRIX_SAVE_FLAG);
        canvas.scale(mScale, mScale);
        mMovie.draw(canvas, mLeft / mScale, mTop / mScale);
        canvas.restore();
    }

    @SuppressLint("NewApi")
    @Override
    public void onScreenStateChanged(int screenState) {
        super.onScreenStateChanged(screenState);
        mVisible = screenState == SCREEN_STATE_ON;
        invalidateView();
    }

    @SuppressLint("NewApi")
    @Override
    protected void onVisibilityChanged(View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        mVisible = visibility == View.VISIBLE;
        invalidateView();
    }

    @Override
    protected void onWindowVisibilityChanged(int visibility) {
        super.onWindowVisibilityChanged(visibility);
        mVisible = visibility == View.VISIBLE;
        invalidateView();
    }

}

anim->frame.xml

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false" >

    <item
        android:drawable="@drawable/image_01"
        android:duration="150"/>
    <item
        android:drawable="@drawable/image_02"
        android:duration="150"/>

</animation-list>

loading_dialog.xml

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

    <LinearLayout
        android:id="@+id/load_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="visible"
        android:gravity="center"
        android:orientation="vertical" >

        <ImageView
            android:id="@+id/load_imgv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@anim/frame"
            android:scaleType="center" />

        <TextView
            android:id="@+id/load_tetv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="正在加载中.."
            android:textSize="20sp" />
    </LinearLayout>

    <com.example.loading.GifView
        android:id="@+id/load_gifv"
        android:layout_width="60dp"
        android:layout_height="40dp"
        android:layout_centerInParent="true"
        android:layout_gravity="center_horizontal"
        android:visibility="gone"
        android:enabled="false" />

</RelativeLayout>

main_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_gravity="center"
        android:onClick="showmeidialog"
        android:text="点击加载美团对话框" />


    <Button
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_gravity="center"
        android:onClick="showGifdialog"
        android:text="点击加载Gif动画" />

</LinearLayout>

styleable.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="GifView">
        <attr name="gif" format="reference" />
        <attr name="paused" format="boolean" />
    </declare-styleable>
    <declare-styleable name="CustomTheme">
        <attr name="gifViewStyle" format="reference" />
    </declare-styleable>

</resources>
<style name="Widget_GifView" >
</style>

项目下载

一个简单好用的LoadingDialog

写在前面 还记得以前在网上看到过一个LoadingDialog,感觉还挺不错的,可惜只有一个Loading,配套的错误和正确的反馈都没,一直觉得挺遗憾的,今天花了一些时间把他补全了。今天上多说找了下...
  • a214024475
  • a214024475
  • 2016年11月08日 19:30
  • 2684

移动开发----一个简单能用的LoadingDialog

项目介绍: .idea add two methods for users Nov 10, 2016 LoadingDialog add two methods for...
  • zhanwei0102
  • zhanwei0102
  • 2016年11月12日 15:03
  • 556

自定义LoadingDialog

1.继承dialog  2.一个主题样式文件  3.一个布局文件来加载  4.一个anim文件 1.自定义Dialog public class MyDialog extends Dia...
  • qq_33645265
  • qq_33645265
  • 2016年12月08日 17:10
  • 471

Android自定义类似ProgressDialog效果的Dialog

Android自定义类似ProgressDialog效果的Dialog. 方法如下: 1.首先准备两张自己要定义成哪样子的效果的图片和背景图片(也可以不要背景)。 如我要的效果: ...
  • qjlhlh
  • qjlhlh
  • 2012年09月14日 15:17
  • 126545

自定义加载框LoadingDialog

  • 2017年09月23日 16:05
  • 182KB
  • 下载

Android自定义loading Dialog

  • 2014年10月28日 18:10
  • 2.49MB
  • 下载

加载对话框(LoadingDialog)

加载对话框(LoadingDialog)
  • qq_32594139
  • qq_32594139
  • 2016年08月25日 14:18
  • 68

【Android自定义View实战】之自定义项目通用的加载等待对话框LoadingDialog

在平时的Android开发中,我们难免会遇到像登陆.注册.获取数据这样的操作,而用的的网络状况不同,导致操作需要等待一定的时间,那么为了友好期间,我们需要给用户提供一个在操作完之后的一个友好的等待界面...
  • u010785585
  • u010785585
  • 2016年10月30日 11:51
  • 7290

Android在WebView加载数据时展示loading的Dialog

Android在WebView就在数据时展示loading的Dialog
  • C_xundaozhe
  • C_xundaozhe
  • 2016年12月27日 15:18
  • 1797

【Android】Android开发之常用的loading等待效果实现,仿微博等待动画。两种实现方式详解

作者:程序员小冰 (转载请说明出处)博客地址:http://blog.csdn.net/qq_21376985长期维护的Android项目,里面包括常用功能实现,以及知识点详解, 当然还有Java中的...
  • qq_21376985
  • qq_21376985
  • 2016年10月18日 11:24
  • 17096
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:自定义Loading Dialog,图片(仿美团)、GIF图片加载两种方式
举报原因:
原因补充:

(最多只允许输入30个字)