经过(一)的基础介绍,现在小编将在(二)中给大家介绍以下几种效果:
1、点击查看组图(模拟QQ空间图片浏览)
2、缩略图放大(自定义Dialog)
3、动态加载进度条
一、点击产看组图(模拟QQ空间图片浏览)
Android提供给我们一个专门处理这种问题的插件:Gallary。顾名思义,就是展示图片的画廊。它可以实现图片的成组浏览,包括选中高亮,循环滚动等效果,可以实现诸如网站的滚动图片效果。当然gallery的使用还是需要adapter的介入。今天带大家做一个小例子,里面便会介绍gallery的所有常用方法。代码拿来:
首先是自定义的Gallery的图片适配器:
package com.teach.gallery;
/**
* @author Arthur Lee
* @time 05/01/2014
* */
import java.util.List;
import com.teach.demo.R;
import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
/**
* ImageAdapter用来配置gallery,之所以重写gallery的适配器,
* 在于组图资源在实际开发中是不固定的,我们需要不断的从服务端获取当前用户的信息,
* 因此我们需要一个可以通用的适配器*/
public class ImageAdapter extends BaseAdapter{
private List<Integer> img; //存放图片 ID的数组,这里也可以设置成存放图片保存路径的
private Context context; //获取当前Activity();
public ImageAdapter(Context context,List<Integer> img){
this.context = context;
this.img = img;
}
//获取组图的容量
@Override
public int getCount() {
// TODO Auto-generated method stub
return img.size();
/**①
* 如果我们要是想实现循环付滚动图片,只需改动两个地方,一是把本处的返回值改为
* return Integer.MAX_VALUE;
* 即返回整形的最大值
* 二是在getView中通过取余的方法获取当前img中的数据
* 理论依据与循环链表的实现一致,*/
}
//获取当前图片
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return img.get(position);
}
//获取当前图片的ID
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
// TODO Auto-generated method stub
ImageView image = new ImageView(context);
/**②
*将本处修改为image.setBackgroundResource(img.get(position%img.size()));
* 即可实现循环滑动*/
image.setBackgroundResource(img.get(position));
//设置图片形式为居中缩放
image.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
/**
* 添加本句话可是想选中区域高亮的效果*/
//image.setBackgroundColor(Color.alpha(1));
return image;
}
}
接下来是提供图片资源的Factory:
package com.teach.gallery;
/**
* @author Arthur Lee
* @time 05/01/2014
* */
import java.util.ArrayList;
import java.util.List;
import com.teach.demo.R;
public class ImageFactory {
/**
* 本方法用于处理从服务端发送回来的数据,在此处先简单设置不详细叙述,具有方法在第八讲介绍*/
public static final List<Integer> getImgResource(){
List<Integer> list = new ArrayList<Integer>();
for(int i=0;i<5;i++){
list.add(R.drawable.ic_launcher);
}
return list;
}
}
gallery所对用的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" >
<!-- @author Arthur Lee -->
<!-- 垂直分布三个,以ABC标记 -->
<!-- A -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"></LinearLayout>
<!-- B -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="4">
<!-- 水平分布三个,以123标记 -->
<!-- 1 -->
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"></LinearLayout>
<!-- 2 -->
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="4">
<!-- 组图浏览区域 -->
<Gallery
android:id="@+id/third_gallery"
android:gravity="center_vertical|center_horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
<!-- 3 -->
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"></LinearLayout>
</LinearLayout>
<!-- C -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"></LinearLayout>
</LinearLayout>
其效果图如下:当然小编偷懒了,大家就凑合着看看吧,具体的其他功能小编在代码中已注明,大家可以尝试的去修改一下,便会体会到Gallery的魅力了。
二、点击查看缩略图
带大家做这个效果,其实是想教大家如何自定义弹出框的样式,虽然Android的弹出框很方便实用,但我们还是想把它用到极致,所以Android便提供了一个getView()的方法,让开发者们可以去DIY了。这个缩略图放大就是DIY了一个专门放置图片的View,通过放大Dialog和View的宽高,实现小图的放大效果。大家在制作其他DIY弹出框时,也是按照同样的流程即可,只需改变其中的控件就行了。代码如下:
//设置自定义的对话框
public void setDIYDialog(){
View view = inflater.inflate(R.layout.third_image, null);
ImageView imgView = (ImageView)view.findViewById(R.id.third_imageview);
TextView tView = (TextView)view.findViewById(R.id.third_image_tx);
imgView.setBackgroundResource(R.drawable.ic_launcher);
tView.setText("这是一个缩略图放大效果");
//放大图片至屏幕的90%
/**
* LayoutParams 是ViewGroup的一个子类,用以设置当前param的长宽值*/
LayoutParams para = imgView.getLayoutParams();
para.height = MainActivity.displayHeight/10*9;
para.width = MainActivity.displayWidth/10*9;
imgView.setLayoutParams(para);
final AlertDialog dialog = new AlertDialog.Builder(context).create();
//去除边框
dialog.setView(view,0,0,0,0);
dialog.show();
//控制Dialog的大小,将其和图片放大到同样大小
WindowManager.LayoutParams params = dialog.getWindow().getAttributes();
params.width = MainActivity.displayWidth/10*9;
params.height = MainActivity.displayHeight/10*9;
//改变AlertDialog至屏幕的90%
dialog.getWindow().setAttributes(params);
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
/**
* 用cancel和dismiss关闭Dialog的效果一样,只是它们在后台调用的机制不同罢了*/
dialog.cancel();
}
});
}
//在MainActivty中获取当前屏幕的宽高,为后面的缩放提供数据
DisplayMetrics dm=new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
displayWidth=dm.widthPixels;
displayHeight=dm.heightPixels-80;
其对应的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" >
<!-- @author Arthur Lee -->
<!-- 垂直分布三个,以ABC标记 -->
<!-- A -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"></LinearLayout>
<!-- B -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="4">
<!-- 水平分布三个,以123标记 -->
<!-- 1 -->
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"></LinearLayout>
<!-- 2 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight="4">
<!-- 缩放区域 -->
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/third_imageview"
android:scaleType="centerInside"
android:layout_weight="7"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/third_image_tx"
android:layout_weight="1"
android:text=""/>
</LinearLayout>
<!-- 3 -->
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"></LinearLayout>
</LinearLayout>
<!-- C -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"></LinearLayout>
</LinearLayout>
三、动态加载进度条
在下载图片、文件、升级软件的过程中,为了提高用户体验水平,显示进度条是再好不过的事情。控制进度条的下载很简单,就是一个单线程的操作,我们只需在加载完成时,在线程中发出一个Message给主线程(整个Activity就是一个主线程,一个APP就只有一个主线程,其他的都是子线程),改变当前的UI状态即可。
代码如下:
//设置动态进度条
public void setAutoProgress(){
int count = 0;
pDialog = new ProgressDialog(context);
//设置进度条模式为水平模式。
pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
//是够可通过点击页面返回
pDialog.setCancelable(true);
//进度条的显示是否不明确
pDialog.setIndeterminate(false);
//设计进度条的容量,可以指定为下载文件或zip包的大小,这里假设为1000
pDialog.setProgress(1000);
pDialog.setTitle("进度条");
pDialog.setMessage("这是提示信息");
pDialog.show();
time.start();
//
//
}
Thread time = new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
try{
while(count<101){
pDialog.setProgress(count++);
Thread.sleep(100);
}
/**
*我们无法在单独的线程中改变当前UI的状态,
*只有通过Handler向主线程传送消息,通知主线程来改变当前UI状态 */
mHandler.sendEmptyMessage(0);
}catch(Exception e){
e.printStackTrace();
}
}};
//设置Handler参数 ,用来通知主线程做出相应的规划
Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
//Message的what方法是用来传送数值的,这种方法最通用
//不懂switch的回去看书
switch(msg.what){
case 0:
pDialog.cancel();
break;
default:
break;
}
}
};
效果图如下:
当然:这些程序依然部署在我们第一讲中做的Fragment中,没看的观众可以回顾一下点击打开链接,
下面就是整合后的代码原貌:
package com.teach.dialog;
/**
* @author Arthur Lee
* @time 04/21/2014
* */
import java.util.ArrayList;
import java.util.List;
import com.teach.demo.MainActivity;
import com.teach.demo.R;
import com.teach.gallery.ImageAdapter;
import com.teach.gallery.ImageFactory;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.TextView;
public class DialogSpecialHelper {
private Context context;
private LayoutInflater inflater;
private Gallery gallery;
private int count = 0;
private ProgressDialog pDialog;
public DialogSpecialHelper(Context context){
this.context = context;
this.inflater = LayoutInflater.from(context);
}
//设置自定义的对话框
public void setDIYDialog(){
View view = inflater.inflate(R.layout.third_image, null);
ImageView imgView = (ImageView)view.findViewById(R.id.third_imageview);
TextView tView = (TextView)view.findViewById(R.id.third_image_tx);
imgView.setBackgroundResource(R.drawable.ic_launcher);
tView.setText("这是一个缩略图放大效果");
//放大图片至屏幕的90%
/**
* LayoutParams 是ViewGroup的一个子类,用以设置当前param的长宽值*/
LayoutParams para = imgView.getLayoutParams();
para.height = MainActivity.displayHeight/10*9;
para.width = MainActivity.displayWidth/10*9;
imgView.setLayoutParams(para);
final AlertDialog dialog = new AlertDialog.Builder(context).create();
//去除边框
dialog.setView(view,0,0,0,0);
dialog.show();
//控制Dialog的大小,将其和图片放大到同样大小
WindowManager.LayoutParams params = dialog.getWindow().getAttributes();
params.width = MainActivity.displayWidth/10*9;
params.height = MainActivity.displayHeight/10*9;
//改变AlertDialog至屏幕的90%
dialog.getWindow().setAttributes(params);
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
/**
* 用cancel和dismiss关闭Dialog的效果一样,只是它们在后台调用的机制不同罢了*/
dialog.cancel();
}
});
}
//实现浏览图组的功能
public void setGallary(){
View view = inflater.inflate(R.layout.third_gallery, null);
gallery = (Gallery)view.findViewById(R.id.third_gallery);
List<Integer> img = new ArrayList<Integer>();
img = ImageFactory.getImgResource();
ImageAdapter iAapter = new ImageAdapter(context,img);
gallery.setAdapter(iAapter);
//设置组图开始浏览的位置。
/**③
* 该处还可以配合ImageAdapter中的①②,实现循环浏览,只需把setSelection的起始位置设的足够大即可
* 例如:gallery.setSelection(img.size()*50);*/
gallery.setSelection(0);
//当前图片没有选中时,处于阴影区域,只有选中时,才会高亮显示,与ImageAdaper中的getView方法配合使用。
gallery.setUnselectedAlpha(0.3f);
//设置图片间距
gallery.setSpacing(50);
/**
*用于监听当前图片点击选中时的操作。滑动时不触发 */
//gallery.setOnItemClickListener(listener);
/**
* 用于监听当前图片滑动选中时的操作*/
//gallery.setOnItemSelectedListener(listener);
final AlertDialog dialog = new AlertDialog.Builder(context).create();
//去除边框
dialog.setView(view,0,0,0,0);
dialog.show();
//点击当前图片时退出浏览
gallery.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
dialog.dismiss();
}
});
}
//设置动态进度条
public void setAutoProgress(){
int count = 0;
pDialog = new ProgressDialog(context);
//设置进度条模式为水平模式。
pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
//是够可通过点击页面返回
pDialog.setCancelable(true);
//进度条的显示是否不明确
pDialog.setIndeterminate(false);
//设计进度条的容量,可以指定为下载文件或zip包的大小,这里假设为1000
pDialog.setProgress(1000);
pDialog.setTitle("进度条");
pDialog.setMessage("这是提示信息");
pDialog.show();
time.start();
//
//
}
Thread time = new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
try{
while(count<101){
pDialog.setProgress(count++);
Thread.sleep(100);
}
/**
*我们无法在单独的线程中改变当前UI的状态,
*只有通过Handler向主线程传送消息,通知主线程来改变当前UI状态 */
mHandler.sendEmptyMessage(0);
}catch(Exception e){
e.printStackTrace();
}
}};
//设置Handler参数 ,用来通知主线程做出相应的规划
Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
//Message的what方法是用来传送数值的,这种方法最通用
//不懂switch的回去看书
switch(msg.what){
case 0:
pDialog.cancel();
break;
default:
break;
}
}
};
}
package com.teach.demo;
/**
* @author Arthur Lee
* @time 04/08/2014
* */
import com.teach.dialog.DialogSpecialHelper;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageButton;
public class ThirdFragment extends Fragment{
//缓存视图
private View view;
private DialogSpecialHelper dsHelper;
private Button bt_special_gallery,bt_special_progress;
private ImageButton bt_special_picture;
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
//如果当前视图为空,初始化视图
if(view == null){
//指定当前视图在viewpager中显示的是view_first。xml,通过LayoutInflater来指定.
view = inflater.inflate(R.layout.view_third, null);
}
//指定当前视图的父类,以便调用父类的移除功能。
ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null) {
parent.removeView(view);
}
bt_special_gallery = (Button) view.findViewById(R.id.bt_special_gallery);
bt_special_picture = (ImageButton) view.findViewById(R.id.bt_special_picture);
bt_special_progress = (Button)view.findViewById(R.id.bt_special_progress);
dsHelper = new DialogSpecialHelper(getActivity());
bt_special_gallery.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
dsHelper.setGallary();
}
});
bt_special_picture.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
dsHelper.setDIYDialog();
}
});
bt_special_progress.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
dsHelper.setAutoProgress();
}
});
return view;
}
}
虽然写博客很麻烦,不过只要大家能学到东西,小编我就心满意足了。
最后还是一句话结尾:我不是一个好的程序员,因为我只会默默奉献。