自定义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,配套的错误和正确的反馈都没,一直觉得挺遗憾的,今天花了一些时间把他补全了。今天上多说找了下...

使用Dialog实现全局Loading加载框

Dialog实现全局Loading加载框 很多人在实现Loading加载框的时候,都是在当前的页面隐藏一个Loading布局,需要加载的时候,显示出来,加载完再隐藏 使用Dialog实现...

Android自定义类似ProgressDialog效果的Dialog

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

jquery 处理页面弹出层查询数据等待的操作(gif图片加载等待)

$(document).ready(function(){     layer.load(0); });

Android 自定义dialog(封装好的)

喜欢把用过的东西总结一下,既可以分享,以后自己用的时候也方便查;废话不多说,先看效果: 这是一个很常用的dialog ,封装一个是有必要的,用的地方太多了,实现步骤: 1:创建一个progress_d...

gif格式图片在安卓中的显示(自定义GifView)

在这里主要用的是:android中的android.graphics.Movie 这个类,这是android提供给我们的一个非常方便的工具。 首先,重写控件View,自定义一个展示gif图的GifV...

仿美团loading加载中的动画

仿美团loading加载中动画 整理来自: Android应用之——仿美团loading加载中动画 ;Android 播放Gif 动画 前言 在Android 中是不支持直接使用Gif 图片关...
  • vane918
  • vane918
  • 2017年04月12日 11:48
  • 348

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

【Android】让你的对话框炫起来!漂亮动画效果的Dialog

一个有漂亮动画效果的Dialog,类似于(Nifty Modal Window Effects),效果是模仿里面实现的。GIF有些卡,实际效果很好,(点这里)查看效果...

仿美团加载动画效果

这两天在用美团的时候,平时中没有注意的一个小细节,今天注意到了,就是在进入新页面还没有加载数据的时候,我们都可以看到一个小人像是在跑步,于是我非常好奇这个东西是怎么做的呢?于是乎我就把它的apk下载下...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:自定义Loading Dialog,图片(仿美团)、GIF图片加载两种方式
举报原因:
原因补充:

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