本文參加第二屆Google大學生暑期博客分享大賽
相信你們對Gallery這個控件是再喜好不過了,用它能夠作出很炫的效果,這得意於Android優良的架構和MVC設計模式的
便利。下面我會介紹一個比較炫的自定義的Gallery效果。先上效果圖:
如圖,主要效果包括,中央文字變大,變亮,出現倒影,未選中項變小,變暗,gallery減慢滑動速度,循環gallery展
示。
因爲涉及公司項目,這裏只貼關鍵代碼和xml文檔。
首先默認的Gallery滑動時,滾動速度很快,會致使某些項一閃而過看不清楚,解決的辦法是繼承Gallery,自定義一個
CustomGallery類,覆蓋Gallery的onFling()方法,讓它返回false就好了,代碼以下
package com.widget;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.Gallery;
public class CustomGallery extends Gallery {
public CustomGallery(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public boolean onFling (MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
}
接下來就是在xml文件中如何調用這個自定義的控件類的問題,解決方法很簡單
<LinearLayout android:id="@+id/gallerylayout"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<com.widget.CustomGallery
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:spacing="10dip" android:unselectedAlpha="0.5" android:id="@+id/gallery"
android:layout_marginTop="36dip" />
</LinearLayout>
須要注意的是,Android支持的自定義控件類的構造函數,須要有Context和AttributeSet兩個參數,不然會報異常!
另外
android:unselectedAlpha="0.5"
這個屬性能夠設置未選中項的半透明度,設置爲0.5,這樣有突顯選中項的效果。
此時運行程序並不能顯示咱們自定義的Gallery,緣由是,咱們尚未向Gallery中添加數據,而向Gallery中添加數據需
要使用
Gallery的setAdapter方法,經過適配器來進行添加顯示項,這裏咱們把大學的名稱做爲顯示數據加入到適配器中,因爲須要處理選
中項的倒影效果和變大效果,因而咱們自定義一個Adapter來進行處理,代碼以下
根據MVC,先是數據模型類University
public class University{
private String name; // 學校名稱
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
而後是自定義的Adapter
public import java.util.ArrayList;
import com.model.Channel;
import com.util.BitmapUtil;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
public class UniversityAdapter extends BaseAdapter {
private Context context;
private ArrayList<University> universityList;
public UniversityAdapter(Context context, ArrayList<University> universityList) {
this.context = context;
this.universityList = universityList;
}
//這裏返回一個較大整數是爲了實現Gallery的循環播放
@Override
public int getCount() {
// TODO Auto-generated method stub
return Integer.MAX_VALUE;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
private int select = 0;
public void notifyDataSetChanged(int albumId) {
select = albumId;
super.notifyDataSetChanged();
}
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ImageView imageView = new ImageView(context);//初始化ImageView,用來顯示各項
if (select == position) {//當此項是選中項時,對起進行特殊處理
University pro = universityList.get(position % universityList.size());//要實現循環播放,這
裏須要對數據大小進行求餘
imageView.setImageBitmap(BitmapUtil.createReflectedImage(BitmapUtil
.createTxtImage(pro.getName(), 28)));//這裏經過自定義的BitmapUtil類中的兩個
方法,實現了倒影效果
} else {
University pro = universityList.get(position % universityList.size());
imageView.setImageBitmap(BitmapUtil.createTxtImage(pro.getName(),
22));//這設置文字大小爲22。實現了未選中項的變小效果
}
return imageView;
}
上面代碼中的BitmapUtil是封裝好的Bitmap處理工具類,包括了傳入文字和字體大小,返回繪製好的Bitmap 和傳入Bitmap返回下方
加入了倒影效果的Bitmap的函數。代碼以下
package com.util;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Shader.TileMode;
public class BitmapUtil {
public static Bitmap createTxtImage(String txt, int txtSize) {
Bitmap mbmpTest = Bitmap.createBitmap(txt.length() * txtSize + 4,
txtSize + 4, Config.ARGB_8888);
Canvas canvasTemp = new Canvas(mbmpTest);
Paint p = new Paint();
p.setAntiAlias(true);
p.setColor(Color.WHITE);
p.setTextSize(txtSize);
canvasTemp.drawText(txt, 2, txtSize - 2, p);
return mbmpTest;
}
public static Bitmap createReflectedImage(Bitmap originalImage) {
// The gap we want between the reflection and the original image
final int reflectionGap = 0;
int width = originalImage.getWidth();
int height = originalImage.getHeight();
// This will not scale but will flip on the Y axis
Matrix matrix = new Matrix();
matrix.preScale(1, -1);
// Create a Bitmap with the flip matrix applied to it.
// We only want the bottom half of the image
Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,
height / 2, width, height / 2, matrix, false);
// Create a new bitmap with same width but taller to fit reflection
Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
(height + height / 2), Config.ARGB_8888);
// Create a new Canvas with the bitmap that's big enough for
// the image plus gap plus reflection
Canvas canvas = new Canvas(bitmapWithReflection);
// Draw in the original image
canvas.drawBitmap(originalImage, 0, 0, null);
// Draw in the gap
Paint defaultPaint = new Paint();
canvas.drawRect(0, height, width, height + reflectionGap, defaultPaint);
// Draw in the reflection
canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
// Create a shader that is a linear gradient that covers the reflection
Paint paint = new Paint();
LinearGradient shader = new LinearGradient(0,
originalImage.getHeight(), 0, bitmapWithReflection.getHeight()
+ reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP);
// Set the paint to use this shader (linear gradient)
paint.setShader(shader);
// Set the Transfer mode to be porter duff and destination in
paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
// Draw a rectangle using the paint with our linear gradient
canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
+ reflectionGap, paint);
return bitmapWithReflection;
}
}
最後就是主界面代碼中對Gallery的調用了,關鍵代碼以下
private CustomGallery gallery;
private UniversityAdapter pAdapter;
private ArrayList<University> universityList = new ArrayList<University>();
private void init(){
pAdapter = new UniversityAdapter(MainActivity.this, universityList);//初始化咱們自定義的Adapter
University p = new University();
p.setName("電子科技大學");
universityList .add(p);
University p1 = new University();
p1.setName("清華大學");
universityList .add(p1);
University p2 = new University();
p2.setName("北京大學");
universityList .add(p2);
gallery.setAdapter(pAdapter);//設置Gallery顯示的內容
gallery.setSelection(Integer.MAX_VALUE / 2);//經過setSelection() 能夠設置當前選中的元素,這裏咱們將
其設置在中間
gallery.setOnItemSelectedListener(this);//這裏對Item項進行監聽,以實現刷新顯示的效果
}
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
pAdapter.notifyDataSetChanged(arg2);//arg2會返回當前選中項的位置,調用此方法,通知更新
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
代碼貼完了,有疑問的能夠發我郵件,郵箱是uestccokey@gmail.com
但願你們最後都能把程序跑起來,作出更好更實用的效果。
各位路過的哥們兒們,幫小弟投個票吧,http://www.google.com/intl/zh-CN/daxue/blog/vote.html#tab2
下面選李可,電子科技大學,謝謝了,哈哈
下一期咱們將會講解如何經過xml更簡單的自定義各類控件,但願你們繼續支持