Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 781|回复: 0

玩转Android 之 绚丽的自定义Gallery

[复制链接]

该用户从未签到

发表于 2012-3-23 11:49:33 | 显示全部楼层 |阅读模式
相信大家对Gallery这个控件是再喜爱不过了,用它可以做出很炫的效果,这得意于Android优良的架构和MVC设计模式的
便利。下面我会介绍一个比较炫的自定义的Gallery效果。先上效果图:


如图,主要效果包括,中央文字变大,变亮,出现倒影,未选中项变小,变暗,gallery减慢滑动速度,循环gallery展
示。
         由于涉及公司项目,这里只贴关键代码和xml文档。
         首先默认的Gallery滑动时,滚动速度很快,会导致某些项一闪而过看不清楚,解决的办法是继承Gallery,自定义一个

CustomGallery类,覆盖Gallery的onFling()方法,让它返回false就行了,代码如下
    [li]package com.widget;[/li][li]02[/li][li]import android.content.Context;[/li][li]03[/li][li]import android.util.AttributeSet;[/li][li]04[/li][li]import android.view.MotionEvent;[/li][li]05[/li][li]import android.widget.Gallery;[/li][li]06[/li][li][/li][li]07[/li][li]public class CustomGallery extends Gallery {[/li][li]08[/li][li][/li][li]09[/li][li]    public CustomGallery(Context context, AttributeSet attrs) {[/li][li]10[/li][li]        super(context, attrs);[/li][li]11[/li][li]        // TODO Auto-generated constructor stub[/li][li]12[/li][li]    }[/li][li]13[/li][li]    public boolean onFling (MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {[/li][li]14[/li][li]        return false;[/li][li]15[/li][li]    }[/li][li]16[/li][li][/li][li]17[/li][li]}
    [/li]

复制代码
接下来就是在xml文件中如何调用这个自定义的控件类的问题,解决方法很简单

    [li]<LinearLayout android:id="@+id/gallerylayout"[/li][li]2[/li][li]    android:layout_width="fill_parent" android:layout_height="fill_parent">[/li][li]3[/li][li]    <com.widget.CustomGallery[/li][li]4[/li][li]        android:layout_width="fill_parent" android:layout_height="wrap_content"[/li][li]5[/li][li]        android:spacing="10dip" android:unselectedAlpha="0.5" android:id="@+id/gallery"[/li][li]6[/li][li]        android:layout_marginTop="36dip" />[/li][li]7[/li][li]</LinearLayout>
    [/li]

复制代码
需要注意的是,Android支持的自定义控件类的构造函数,需要有Context和AttributeSet两个参数,否则会报异常!
另外
android:unselectedAlpha="0.5"
这个属性可以设置未选中项的半透明度,设置为0.5,这样有突显选中项的效果。
         此时运行程序并不能显示我们自定义的Gallery,原因是,我们还没有向Gallery中添加数据,而向Gallery中添加数据需

要使用
Gallery的setAdapter方法,通过适配器来进行添加显示项,这里我们把大学的名称作为显示数据加入到适配器中,由于需要处理选

中项的倒影效果和变大效果,于是我们自定义一个Adapter来进行处理,代码如下
根据MVC,先是数据模型类University
    [li]public class University{[/li][li]02[/li][li]    private String name;  // 学校名称[/li][li]03[/li][li][/li][li]04[/li][li]    public String getName() {[/li][li]05[/li][li]        return name;[/li][li]06[/li][li]    }[/li][li]07[/li][li][/li][li]08[/li][li]    public void setName(String name) {[/li][li]09[/li][li]        this.name = name;[/li][li]10[/li][li]    }[/li][li]11[/li][li]}
    [/li]

复制代码
然后是自定义的Adapter
    [li]public import java.util.ArrayList;[/li][li]02[/li][li]import com.model.Channel;[/li][li]03[/li][li]import com.util.BitmapUtil;[/li][li]04[/li][li]import android.content.Context;[/li][li]05[/li][li]import android.view.View;[/li][li]06[/li][li]import android.view.ViewGroup;[/li][li]07[/li][li]import android.widget.BaseAdapter;[/li][li]08[/li][li]import android.widget.ImageView;[/li][li]09[/li][li][/li][li]10[/li][li][/li][li]11[/li][li]public class UniversityAdapter extends BaseAdapter {[/li][li]12[/li][li][/li][li]13[/li][li]    private Context context;[/li][li]14[/li][li]    private ArrayList<University> universityList;[/li][li]15[/li][li][/li][li]16[/li][li]    public UniversityAdapter(Context context, ArrayList<University> universityList) {[/li][li]17[/li][li]        this.context = context;[/li][li]18[/li][li]        this.universityList = universityList;[/li][li]19[/li][li]    }[/li][li]20[/li][li]        //这里返回一个较大整数是为了实现Gallery的循环播放[/li][li]21[/li][li]    @Override[/li][li]22[/li][li]    public int getCount() {[/li][li]23[/li][li]        // TODO Auto-generated method stub[/li][li]24[/li][li]        return Integer.MAX_VALUE;[/li][li]25[/li][li]    }[/li][li]26[/li][li][/li][li]27[/li][li]    @Override[/li][li]28[/li][li]    public Object getItem(int position) {[/li][li]29[/li][li]        // TODO Auto-generated method stub[/li][li]30[/li][li]        return position;[/li][li]31[/li][li]    }[/li][li]32[/li][li][/li][li]33[/li][li]    @Override[/li][li]34[/li][li]    public long getItemId(int position) {[/li][li]35[/li][li]        // TODO Auto-generated method stub[/li][li]36[/li][li]        return position;[/li][li]37[/li][li]    }[/li][li]38[/li][li][/li][li]39[/li][li]    private int select = 0;[/li][li]40[/li][li][/li][li]41[/li][li]    public void notifyDataSetChanged(int albumId) {[/li][li]42[/li][li]        select = albumId;[/li][li]43[/li][li]        super.notifyDataSetChanged();[/li][li]44[/li][li]    }[/li][li]45[/li][li]    public View getView(int position, View convertView, ViewGroup parent) {[/li][li]46[/li][li]        // TODO Auto-generated method stub[/li][li]47[/li][li]        ImageView imageView = new ImageView(context);//初始化ImageView,用来显示各项[/li][li]48[/li][li]        if (select == position) {//当此项是选中项时,对起进行特殊处理[/li][li]49[/li][li]            University pro = universityList.get(position % universityList.size());//要实现循环播放,这[/li][li]50[/li][li][/li][li]51[/li][li]里需要对数据大小进行求余[/li][li]52[/li][li]            imageView.setImageBitmap(BitmapUtil.createReflectedImage(BitmapUtil[/li][li]53[/li][li]                    .createTxtImage(pro.getName(), 28)));//这里通过自定义的BitmapUtil类中的两个[/li][li]54[/li][li][/li][li]55[/li][li]方法,实现了倒影效果[/li][li]56[/li][li]        } else {[/li][li]57[/li][li]            University pro = universityList.get(position % universityList.size());[/li][li]58[/li][li]            imageView.setImageBitmap(BitmapUtil.createTxtImage(pro.getName(),[/li][li]59[/li][li]                    22));//这设置文字大小为22。实现了未选中项的变小效果[/li][li]60[/li][li]        }[/li][li]61[/li][li]        return imageView;[/li][li]62[/li][li]    }
    [/li]

复制代码
上面代码中的BitmapUtil是封装好的Bitmap处理工具类,包括了传入文字和字体大小,返回绘制好的Bitmap 和传入Bitmap返回下方
回复

使用道具 举报

该用户从未签到

 楼主| 发表于 2012-3-23 11:50:04 | 显示全部楼层
加入了倒影效果的Bitmap的函数。代码如下

package com.util;
02

03
import android.graphics.Bitmap;
04
import android.graphics.Bitmap.Config;
05
import android.graphics.Canvas;
06
import android.graphics.Color;
07
import android.graphics.LinearGradient;
08
import android.graphics.Matrix;
09
import android.graphics.Paint;
10
import android.graphics.PorterDuff.Mode;
11
import android.graphics.PorterDuffXfermode;
12
import android.graphics.Shader.TileMode;
13

14
public class BitmapUtil {
15

16
    public static Bitmap createTxtImage(String txt, int txtSize) {
17
        Bitmap mbmpTest = Bitmap.createBitmap(txt.length() * txtSize + 4,
18
                txtSize + 4, Config.ARGB_8888);
19
        Canvas canvasTemp = new Canvas(mbmpTest);
20
        Paint p = new Paint();
21
        p.setAntiAlias(true);
22
        p.setColor(Color.WHITE);
23
        p.setTextSize(txtSize);
24
        canvasTemp.drawText(txt, 2, txtSize - 2, p);
25
        return mbmpTest;
26
    }
27

28
    public static Bitmap createReflectedImage(Bitmap originalImage) {
29
        // The gap we want between the reflection and the original image
30
        final int reflectionGap = 0;
31

32
        int width = originalImage.getWidth();
33
        int height = originalImage.getHeight();
34

35
        // This will not scale but will flip on the Y axis
36
        Matrix matrix = new Matrix();
37
        matrix.preScale(1, -1);
38

39
        // Create a Bitmap with the flip matrix applied to it.
40
        // We only want the bottom half of the image
41
        Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,
42
                height / 2, width, height / 2, matrix, false);
43

44
        // Create a new bitmap with same width but taller to fit reflection
45
        Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
46
                (height + height / 2), Config.ARGB_8888);
47

48
        // Create a new Canvas with the bitmap that's big enough for
49
        // the image plus gap plus reflection
50
        Canvas canvas = new Canvas(bitmapWithReflection);
51
        // Draw in the original image
52
        canvas.drawBitmap(originalImage, 0, 0, null);
53
        // Draw in the gap
54
        Paint defaultPaint = new Paint();
55
        canvas.drawRect(0, height, width, height + reflectionGap, defaultPaint);
56
        // Draw in the reflection
57
        canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
58

59
        // Create a shader that is a linear gradient that covers the reflection
60
        Paint paint = new Paint();
61
        LinearGradient shader = new LinearGradient(0,
62
                originalImage.getHeight(), 0, bitmapWithReflection.getHeight()
63
                        + reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP);
64
        // Set the paint to use this shader (linear gradient)
65
        paint.setShader(shader);
66
        // Set the Transfer mode to be porter duff and destination in
67
        paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
68
        // Draw a rectangle using the paint with our linear gradient
69
        canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
70
                + reflectionGap, paint);
71

72
        return bitmapWithReflection;
73
    }
74
}


复制代码
最后就是主界面代码中对Gallery的调用了,关键代码如下
private CustomGallery gallery;
02
    private UniversityAdapter pAdapter;
03
    private ArrayList<University> universityList = new ArrayList<University>();
04
        private void init(){
05
        pAdapter = new UniversityAdapter(MainActivity.this, universityList);//初始化我们自定义的Adapter
06
        University p = new University();
07
        p.setName("电子科技大学");
08
        universityList .add(p);
09
        University p1 = new University();
10
        p1.setName("清华大学");
11
        universityList .add(p1);
12
        University p2 = new University();
13
        p2.setName("北京大学");
14
        universityList .add(p2);
15
        gallery.setAdapter(pAdapter);//设置Gallery显示的内容
16
        gallery.setSelection(Integer.MAX_VALUE / 2);//通过setSelection() 可以设置当前选中的元素,这里我们将
17

18
其设置在中间
19
        gallery.setOnItemSelectedListener(this);//这里对Item项进行监听,以实现刷新显示的效果
20
       }
21

22
@Override
23
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
24
            long arg3) {
25
    // TODO Auto-generated method stub
26
    pAdapter.notifyDataSetChanged(arg2);//arg2会返回当前选中项的位置,调用此方法,通知更新
27
}
28

29

30
@Override
31
public void onNothingSelected(AdapterView<?> arg0) {
32
        // TODO Auto-generated method stub
33
}
回复 支持 反对

使用道具 举报

头像被屏蔽

该用户从未签到

发表于 2012-5-8 11:22:54 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

GMT+8, 2025-1-12 02:42 , Processed in 0.370544 second(s), 46 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表