自定义Dialog加载动画

时间:2022-11-01 13:16:18

<pre name="code" class="java">在上篇文章中介绍了模拟登录服务器时出现的加载对话框,不过是使用android 默认的Dialog,那么我们如果想用自己定义的怎么实现呢?下面先讲android的帧动画:

 

     首先是新建一项目,然后在res底下新建一个anim文件夹,新建一个frame.xml(名称自取)文件,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<!--animation-list 动画帧列表 item:每一帧,duration="200" 200毫秒,0.2秒,根据自己情况可以调节 -->
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false" >
<item
android:drawable="@drawable/img01"
android:duration="200"/>
<item
android:drawable="@drawable/img02"
android:duration="200"/>
<item
android:drawable="@drawable/img03"
android:duration="200"/>
<item
android:drawable="@drawable/img04"
android:duration="200"/>
<item
android:drawable="@drawable/img05"
android:duration="200"/>
<item
android:drawable="@drawable/img06"
android:duration="200"/>
<item
android:drawable="@drawable/img07"
android:duration="200"/>
<item
android:drawable="@drawable/img08"
android:duration="200"/>
</animation-list>


对了,忘记说了,先准备动画图片,等会附件里源码会有,然后再修改layout底下的activity_main.xml文件,代码如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
tools:context="com.example.animationtest.MainActivity" >
<ImageView
android:id="@+id/imageview1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@anim/frame"/>
<TextView
android:id="@+id/textview1"
android:layout_below="@id/imageview1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dip"
android:text="@string/text_str" />

<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textview1"
android:layout_below="@+id/textview1"
android:layout_marginTop="51dp"
android:text="开始" />

</RelativeLayout>
布局文件都修改好了,然后再看java文件代码:

package com.example.animationtest;

import android.app.Activity;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

/**
* 小P优优奔跑动画
* @author easy
*
*/
public class MainActivity extends Activity {
//定义动画
private AnimationDrawable mAnimation;
private ImageView imageview1;
private TextView textview1;
private Button button1;
//记录奔跑的旗帜
private static boolean flag=true;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageview1 = (ImageView) findViewById(R.id.imageview1);
textview1 = (TextView) findViewById(R.id.textview1);
button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new OnClickListener(){

@Override
public void onClick(View v) {
// 通过ImageView对象拿到背景显示的AnimationDrawable,必须这一步,实例化动画
mAnimation = (AnimationDrawable) imageview1.getBackground();
//开个线程跑起来
imageview1.post(new Runnable() {
@Override
public void run() {
if(flag){
mAnimation.start();
button1.setText("停止");
textview1.setText("正在奔跑中!");
flag=false;
}else{
mAnimation.stop();
button1.setText("开始");
textview1.setText("正在休息中!");
flag=true;
}
}
});

}

});
}

}

最后运行跑起来!


自定义Dialog加载动画

以上就是android animation帧动画的小例子,下面我们再把上一篇文章介绍的登录例子结合起来,实现自定义加载对话框

在上一篇的源码中直接添加,当然这里是当作dialog来处理,而不是主activty页面,所以在layout里面另创建一个progress_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:layout_gravity="center"
android:orientation="vertical" >

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

<TextView
android:id="@+id/loadingTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/loadingIv"
android:layout_centerHorizontal="true"
android:textSize="16sp"
android:text="正在加载中.." />

</RelativeLayout>

我们要养成良好习惯,写代码一定要体现出能复用的价值,所以这里把实现自定义动画的对话框布局分离出来,新建一个CustomProgressDialog继承ProgressDialog,实现代码:

package com.example.progressdialogdemo;

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

import com.example.progressdialogdemo.R;

/**
* @Description:自定义对话框
*/
public class CustomProgressDialog extends ProgressDialog {

private AnimationDrawable mAnimation;
private ImageView mImageView;
private String mLoadingTip;
private TextView mLoadingTv;
private int mResid;
/**
*
* @param context 上下文
* @param content 提示信息
* @param id 布局的ID
*/
public CustomProgressDialog(Context context, String content, int id) {
super(context);
this.mLoadingTip = content;
this.mResid = id;
//触摸动画之外的地方是否取消动画,这里设置为flase不取消;
setCanceledOnTouchOutside(false);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initView();
initData();
}
//调用时初始化数据
private void initData() {

mImageView.setBackgroundResource(mResid);
// 通过ImageView对象拿到背景显示的AnimationDrawable
mAnimation = (AnimationDrawable) mImageView.getBackground();
// 为了防止在onCreate方法中只显示第一帧的解决方案之一
mImageView.post(new Runnable() {
@Override
public void run() {
mAnimation.start();
}
});
mLoadingTv.setText(mLoadingTip);
}
//调用时初始化布局
private void initView() {
setContentView(R.layout.progress_dialog);
mLoadingTv = (TextView) findViewById(R.id.loadingTv);
mImageView = (ImageView) findViewById(R.id.loadingIv);
}
/**
* 可以看到在代码中,我们使用到一个imageview.post(Runnable r)方法,因为帧动画需要不断的重画,所以必须在线程中运行,
* 否则只能看到第一帧的效果,这和我们做游戏的原理是一样的,一个人物的走动,是有线程在控制图片的不断重画。
* 这个方法onWindowFocusChanged也可以实现,用哪一个也可以
* 这个onWindowFocusChanged指的是这个Activity得到或者失去焦点的时候 就会call,监听actvity焦点的
* 不过通过这个事件可以实现当一个Activity完全加载完毕后,然后就执行,有点像js里面的window.onload=function()
*/
/*@Override
public void onWindowFocusChanged(boolean hasFocus) {
// TODO Auto-generated method stub
mAnimation.start();
super.onWindowFocusChanged(hasFocus);
}*/
}
来看MainActivity里面的代码:

package com.example.progressdialogdemo;

import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

/**
*
* @author easy
* 博客地址:http://blog.csdn.net/gameleague
*/
public class MainActivity extends Activity {
private Boolean isNetError=true;
/** 模拟获取返回的 **/
private String canshu1;
/** 这是你的进度条 **/
private CustomProgressDialog dialog;
/** 这是用于登录成功之后的事件 这里是在本界面显示登录返回的信息 **/
private TextView textView1;
private Button button1;
/** 这是模拟服务器返回登录后的参数,例如json **/
private EditText editText1;
/** new 一个 Handler,这里是要写在onCreate前面 **/
Handler loginHandler = new Handler() {
//得到传递过来的message
public void handleMessage(Message msg) {
isNetError = msg.getData().getBoolean("isNetError");
canshu1 = msg.getData().getString("canshu1");

if (isNetError&&canshu1.equals("admin")) {
Toast.makeText(MainActivity.this, "登录成功:admin",
Toast.LENGTH_SHORT).show();
textView1.invalidate();
textView1.setText("登录成功:admin");
}else{
Toast.makeText(MainActivity.this, "出错了,请输入admin",
Toast.LENGTH_SHORT).show();
textView1.invalidate();
textView1.setText("登录出错了");
}

}
};


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText1 = (EditText) findViewById(R.id.editText1);
textView1 = (TextView) findViewById(R.id.textView1);
button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new OnClickListener(){

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
//调用 LoginDialog 方法
LoginDialog();
}

});

}
/** 进度条,自己可以定义 **/
private void LoginDialog() {
//可以新建不同图片像anim文件夹下的frame文件,随意更换,以达到整个应用公用此方法的目的。
dialog =new CustomProgressDialog(this, "正在加载中...",R.anim.frame);
dialog.show();
// 开一个线程进行登录验证
thread();

}
/*
* 调用公共线程方法
*/
public void thread(){
Thread hideview = new Thread(new LoginFailureHandler());
hideview.start();
}
/** 登录时调用的Runnable **/
public class LoginFailureHandler implements Runnable {

@Override
public void run() {
//这里模拟登录时间延时,可换成登录请求验证什么的
try {
Thread.sleep(5000);//括号里面的5000代表5000毫秒,也就是5秒,可以该成你需要的时间
canshu1 = editText1.getText().toString();
} catch (InterruptedException e) {
e.printStackTrace();
}
//这里写获取到参数之后东西并存在Bundle里面
if(isNetError){
Message message = new Message();
Bundle bundle = new Bundle();
bundle.putBoolean("isNetError", isNetError);
bundle.putString("canshu1", canshu1);
//封装到message里面给Handler发送过去
message.setData(bundle);
loginHandler.sendMessage(message);
//loginHandler处理完毕取消进度条
dialog.dismiss();
}
}
}
}

注释解释的很清楚了,这里不再阐述,把上一篇看懂,再看这一篇一点也不难

看效果图

自定义Dialog加载动画自定义Dialog加载动画


       源码下载点这里,不要分。