本博客運用GridView、ViewFlipper、ImageView等進行界面佈局,使用自定義適配器顯示圖片。通過GestureDetector事件監聽,可手勢滑動查看圖片,並設置圖片左右滑動出、入的效果。
同時這也是中國大學慕課移動終端應用開發的網課作業12,我會持續更新我的作業,如果有需要關注一下吧
說明
1.圖片資源來自於阿里巴巴矢量圖標庫
2.部分內容參考了此篇博客
3.注意版本和AndroidManifest.xml文件的修改
效果圖
代碼部分
主Activity:HomeworkActivity.java
此Activity需要在AndroidManifest.xml上註冊並設置爲首頁
public class HomeworkActivity extends Activity implements GestureDetector.OnGestureListener{
private GridView mGridView1,mGridView2,mGridView3,mGridView4;//定義四個grid view
private int[] mImages1,mImages2,mImages3,mImages4;//定義四個數據集
private HomeWorkAdapter mAdapter1,mAdapter2,mAdapter3,mAdapter4; //定義四個適配器
private GestureDetector mGestureDetector;//定義手勢監測
private ViewFlipper mViewFlipper;//定義view flipper
private Animation[] mAnimations;//定義過渡動畫數組
private final int MIN_DISTANCE = 50;//定義觸發滑動最短距離
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_homework);
mViewFlipper = findViewById(R.id.homework_view_flipper);
initData();
initView();
initAnim();
mGestureDetector = new GestureDetector(this,this);
}
//初始化動畫數組
private void initAnim(){
mAnimations = new Animation[]{
AnimationUtils.loadAnimation(this,R.anim.left_in)
,AnimationUtils.loadAnimation(this,R.anim.left_out)
,AnimationUtils.loadAnimation(this,R.anim.right_in)
,AnimationUtils.loadAnimation(this,R.anim.right_out)
};
}
//初始化子頁面
private void initView(){
mGridView1 = findViewById(R.id.homework_grid_view1);
mAdapter1 = new HomeWorkAdapter(mImages1,HomeworkActivity.this);
mGridView1.setAdapter(mAdapter1);
mGridView1.setNumColumns(3);
//由於子view佈局覆蓋了父view的監聽事件,所以設置子view的監聽也是gestureDetector.onTouchEvent()
mGridView1.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return mGestureDetector.onTouchEvent(event);
}
});
mGridView2 = findViewById(R.id.homework_grid_view2);
mAdapter2 = new HomeWorkAdapter(mImages2,HomeworkActivity.this);
mGridView2.setAdapter(mAdapter2);
mGridView2.setNumColumns(3);
mGridView2.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return mGestureDetector.onTouchEvent(event);
}
});
mGridView3 = findViewById(R.id.homework_grid_view3);
mAdapter3 = new HomeWorkAdapter(mImages3,HomeworkActivity.this);
mGridView3.setAdapter(mAdapter3);
mGridView3.setNumColumns(3);
mGridView3.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return mGestureDetector.onTouchEvent(event);
}
});
mGridView4 = findViewById(R.id.homework_grid_view4);
mAdapter4 = new HomeWorkAdapter(mImages4,HomeworkActivity.this);
mGridView4.setAdapter(mAdapter4);
mGridView4.setNumColumns(3);
mGridView4.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return mGestureDetector.onTouchEvent(event);
}
});
}
//初始化 數據
private void initData(){
int a = R.drawable.img1;
int b = R.drawable.img2;
int c = R.drawable.img3;
int d = R.drawable.img4;
mImages1 = new int[]{a, a, a, a, a, a, a, a, a, a, a, a};
mImages2 = new int[]{b, b, b, b, b, b, b, b, b, b, b, b};
mImages3 = new int[]{c, c, c, c, c, c, c, c, c, c, c, c};
mImages4 = new int[]{d, d, d, d, d, d, d, d, d, d, d, d};
}
/**
* 以下方法是監聽事件
* */
@Override
public boolean onTouchEvent(MotionEvent event) {
return mGestureDetector.onTouchEvent(event);
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
float moveLength = e1.getX() - e2.getX(); //獲取移動距離
Log.d("homeworkTag","e1.getX"+e1.getX());
Log.d("homeworkTag","e2.getX"+e2.getX());
if(moveLength < -MIN_DISTANCE){ //如果距離爲負的,即往右邊滑動大於最小臨界值
mViewFlipper.setInAnimation(mAnimations[0]);
mViewFlipper.setOutAnimation(mAnimations[1]);
mViewFlipper.showNext();//展示下一個
return true;
}else if( moveLength > MIN_DISTANCE ) { //如果距離爲正的,即往左邊滑動大於最小臨界值
mViewFlipper.setInAnimation(mAnimations[2]);
mViewFlipper.setOutAnimation(mAnimations[3]);
mViewFlipper.showPrevious();//展示上一個
return true;
}
return false;
}
@Override
public boolean onDown(MotionEvent e) {
return false;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
@Override
public void onLongPress(MotionEvent e) {
}
}
主佈局文件:activity_homework.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">
<ViewFlipper
android:id="@+id/homework_view_flipper"
android:flipInterval="2000"
android:layout_width="match_parent"
android:layout_height="match_parent">
<GridView
android:id="@+id/homework_grid_view1"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</GridView>
<GridView
android:id="@+id/homework_grid_view2"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</GridView>
<GridView
android:id="@+id/homework_grid_view3"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</GridView>
<GridView
android:id="@+id/homework_grid_view4"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</GridView>
</ViewFlipper>
</LinearLayout>
子佈局界面:homework_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="120dp">
<ImageView
android:layout_centerInParent="true"
android:id="@+id/item_image"
android:layout_width="80dp"
android:layout_height="80dp"/>
</RelativeLayout>
自定義適配器:HomeWorkAdapter.java
繼承自BaseAdapter類
public class HomeWorkAdapter extends BaseAdapter {
private int[] images;
private Context mContext;
public HomeWorkAdapter(int[] images, Context context) {
this.images = images;
mContext = context;
}
@Override
public int getCount() {
return images.length;
}
@Override
public Object getItem(int position) {
return images[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView == null){
convertView = LayoutInflater.from(mContext).inflate(R.layout.homework_item,parent,false);
holder = new ViewHolder();
holder.mImageView = convertView.findViewById(R.id.item_image);
convertView.setTag(holder); //將Holder存儲到convertView中
}else{
holder = (ViewHolder) convertView.getTag();
}
holder.mImageView.setImageResource(images[position]);
return convertView;
}
class ViewHolder{
private ImageView mImageView;
}
}
動畫文件
在res文件夾下新建anim目錄,將以下代碼複製進去
left_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="-100%"
android:toXDelta="0"
android:duration="1000"/>
</set>
left_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0"
android:toXDelta="100%"
android:duration="1000"/>
</set>
right_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="100%"
android:toXDelta="0"
android:duration="1000"/>
</set>
right_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0"
android:toXDelta="-100%"
android:duration="1000"/>
</set>
聊一聊實現的一些細節
1.關於事件監聽
由於子view覆蓋了父view絕大多數地方,導致事件監聽不到,所以我將子view的onTouch()方法也設置爲gestureDetector.onTouchEvent()。
mGridView1.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return mGestureDetector.onTouchEvent(event);
}
});
2.關於滑動方向
在onfling()方法中獲取移動前X軸距離與滑動後X軸距離,通過互減,得出方向與移動距離,並設置最小臨界移動距離,判斷是否要通知mViewFlipper進行切換view
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
float moveLength = e1.getX() - e2.getX(); //獲取移動距離
Log.d("homeworkTag","e1.getX"+e1.getX());
Log.d("homeworkTag","e2.getX"+e2.getX());
if(moveLength < -MIN_DISTANCE){ //如果距離爲負的,即往右邊滑動大於最小臨界值
mViewFlipper.setInAnimation(mAnimations[0]);
mViewFlipper.setOutAnimation(mAnimations[1]);
mViewFlipper.showNext();//展示下一個
return true;
}else if( moveLength > MIN_DISTANCE ) { //如果距離爲正的,即往左邊滑動大於最小臨界值
mViewFlipper.setInAnimation(mAnimations[2]);
mViewFlipper.setOutAnimation(mAnimations[3]);
mViewFlipper.showPrevious();//展示上一個
return true;
}
return false;
}
3.關於數據初始化
我設置了四個頁面,都是GridView,爲了偷懶,我將每一個頁面的圖片都設置爲相同的,但是如果願意的話,可以設置成完全不同的,就和作業要求一樣了
private void initData(){
int a = R.drawable.img1;
int b = R.drawable.img2;
int c = R.drawable.img3;
int d = R.drawable.img4;
mImages1 = new int[]{a, a, a, a, a, a, a, a, a, a, a, a};
mImages2 = new int[]{b, b, b, b, b, b, b, b, b, b, b, b};
mImages3 = new int[]{c, c, c, c, c, c, c, c, c, c, c, c};
mImages4 = new int[]{d, d, d, d, d, d, d, d, d, d, d, d};
}
4.關於BaseAdapter的getView()寫法
我推薦大家在菜鳥教程進行相關學習
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView == null){
convertView = LayoutInflater.from(mContext).inflate(R.layout.homework_item,parent,false);
holder = new ViewHolder();
holder.mImageView = convertView.findViewById(R.id.item_image);
convertView.setTag(holder); //將Holder存儲到convertView中
}else{
holder = (ViewHolder) convertView.getTag();
}
holder.mImageView.setImageResource(images[position]);
return convertView;
}
最後
可能我會粗心大意漏寫些啥在博客裏,如果有錯誤,希望大家指出,我會盡快修正。
咳咳!關注不迷路哈