Android Gallery实现滑动翻页效果

发布日期:2013-01-18 17:08:12

最近在做游戏关卡时,需要实现滑动翻页的效果,而且可以一屏不止显示一页,效果如下:

Gallery实现起来并不难,只需要通过Adapter绑定数据就可以显示了,但是有许多细节需要处理。

1.Gallery本身滑动速度很快,需要重写 onFling方法,把返回值设为false。

2.焦点的问题,这个是最难处理的了,根据我的试验,Adapter上绑定的控件除了LinearLayout和ImageView,其他控件都不能获得焦点,也就是说滑动根本就没有反应,有一种的解决方法是在view.setOnTouchListener()里返回gallery.onTouchEvent(event),这样虽然得到了焦点,但是常按是会出现闪动的现象,效果很不好。而用ImageView的话又监听不到Click和Touch事件,我的解决方法是让控件和控件之间有空隙,滑动屏幕时滑到空隙才会翻页,这种效果还是可以接受的。

上代码:

自定义Gallery:

package com.leefj.game.frogpond;

import android.content.Context;
import android.graphics.Rect;
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;
}
}

布局文件中引用CustomGallery:

android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
android:id=”@+id/gallery”
android:spacing=”100dip”
/>

给gallery绑定数据:

gallery = (Gallery) findViewById(R.id.gallery);
ArrayListpages = new ArrayList();
for( int i=0; i ArrayListitems = new ArrayList();
for( int j=0; j int curNum = i*NUMBER_OF_PAGE+j+1;
LevelItem item = new LevelItem();
item.setNumber(curNum);
if( curNum < app.gLevel )
item.setIconId(R.drawable.passed);
else if( curNum == app.gLevel)
item.setIconId(R.drawable.passing);
else if( curNum < TOTAL_LEVEL +1 )
item.setIconId(R.drawable.nopass);
else
item.setIconId(R.drawable.passed);
items.add(item);
}
pages.add(items);
}
GalleryAdapter adapter = new GalleryAdapter(this,pages);
gallery.setAdapter(adapter);

自定义的Adapter:

public class GalleryAdapter extends BaseAdapter {

private Context context;
private float density;
private ArrayListpages;
private frogPondApp app;
private boolean bClick = true;
public GalleryAdapter(Context context, ArrayListpages){
this.context = context;
this.density = ((LevelActivity)context).density;
this.pages = new ArrayList();
this.pages.addAll(pages);
app = (frogPondApp) context.getApplicationContext();
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return pages.size();
}

@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
//        return pages.get(position);
return position;
}

@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
LinearLayout bgLayout = new LinearLayout(context);
bgLayout.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams topParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);
topParams.gravity = Gravity.CENTER_HORIZONTAL;
topParams.setMargins(0, (int) (64*density), 0, 0);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.CENTER_HORIZONTAL;
LinearLayout.LayoutParams btnParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);
btnParams.setMargins((int)(6*density), (int)(6*density),(int)(6*density),(int)(6*density));
bgLayout.setBackgroundResource(R.drawable.bg_level_item);
ArrayListitems = new ArrayList();
items.addAll(pages.get(position));
for( int i=0; i<3; i++){
LinearLayout hLayout = new LinearLayout(context);
hLayout.setOrientation(LinearLayout.HORIZONTAL);
for( int j=0; j<5; j++ ){
LevelItem item = items.get(i*5+j);
Button btn = new Button(context);
btn.setTextColor(R.color.green);
btn.setTextSize(20*density);
btn.setTypeface(Typeface.SANS_SERIF, Typeface.BOLD_ITALIC);
btn.setGravity(Gravity.CENTER);
if(item.getNumber() btn.setText(item.getNumber()+”");
}
else
btn.setText(“”);
btn.setBackgroundResource(item.getIconId());
btn.setTag(item.getNumber());
btn.setOnTouchListener(mTouch);
hLayout.addView(btn,btnParams);
}
if( i == 0 )
bgLayout.addView(hLayout,topParams);
else
bgLayout.addView(hLayout,params);
}
return bgLayout;
}
private OnTouchListener mTouch = new OnTouchListener(){
@Override
public boolean onTouch(View view, MotionEvent event) {
// TODO Auto-generated method stub
int iTag = (Integer)view.getTag();
float fX = 0;
float fY = 0;
if( event.getAction() == MotionEvent.ACTION_DOWN ){
if( iTag < app.gLevel )
view.setBackgroundResource(R.drawable.passed_pressed);
else if( iTag == app.gLevel)
view.setBackgroundResource(R.drawable.passing_pressed);
else if( iTag < LevelActivity.TOTAL_LEVEL +1 )
view.setBackgroundResource(R.drawable.nopass_pressed);
else
view.setBackgroundResource(R.drawable.passed_pressed);
fX = event.getX();
fY = event.getY();
bClick = true;
return true;
}
else if( event.getAction() == MotionEvent.ACTION_MOVE ){
if( Math.abs(fX-event.getX()) < 2*density || Math.abs(fY-event.getY()) < 2*density)
bClick = true;
else
bClick = false;
return true;
}
else if( event.getAction() == MotionEvent.ACTION_UP ){
Log.v(“onTouch”, “up—–”);
if( iTag < app.gLevel )
view.setBackgroundResource(R.drawable.passed);
else if( iTag == app.gLevel)
view.setBackgroundResource(R.drawable.passing);
else if( iTag < LevelActivity.TOTAL_LEVEL +1 )
view.setBackgroundResource(R.drawable.nopass);
else
view.setBackgroundResource(R.drawable.passed);

if( bClick && iTag < app.gLevel+1){
Intent intent = new Intent(context,GameActivity.class);
intent.putExtra(“level”, iTag);
context.startActivity(intent);
}
return true;
}

return false;
}};
}

由于监听不到OnClick事件,只能在onTouch里模拟click的效果。