項目GitHub地址https://github.com/tikeyc/TNinePlaceGridView_Android https://github.com/tikeyc/TikeycAndroid
玩Android不久,根據iOS實現思路https://github.com/tikeyc/TNinePlaceGridView
封裝了一個。詳情見TNinePlaceGridView
說說我的實現思路:
逐漸掌握了Android開發套路,是時候自己去封裝一些東西了。網上看了一些例子,感覺不是我想要的那種,我希望是直接導入就用,沒有Activity,沒有xml布局文件,全代碼創建那種,使用者用起來直接用到一個類或者兩個類就OK的那種。故此花了一點時間封裝了這么一個九宮格:
需要有這么一個控件,這個控件是一個圖片控件TScallImageView,點擊這個圖片會從圖片位置開始放大至全屏TImageListBgView,點擊后全屏縮小到原來位置,且放大縮小過程背景透明可以看見當前UI界面;這個全屏大部分人可能是start一個Activity(這樣的話還得再功能清單文件添加該Activity,這不是我想要的),這里我直接添加到了window上;這些代碼邏輯主要都寫在TImageListBgView類中。
這里需要獲取圖片相對于window的位置:這里自定義了一個記錄位置信息的類TRect
package com.tikeyc.tikeycandroid.custom.TNinePlaceGridView;/*** Created by public1 on 2017/5/23.*/public class TRect {private int left;private int top;private int width;private int height;public TRect(
int left,
int top,
int width,
int height) {this.left =
left;this.top =
top;this.width =
width;this.height =
height;}public int getLeft() {return left;}public int getTop() {return top;}public int getWidth() {return width;}public int getHeight() {return height;}public void setLeft(
int left) {this.left =
left;}public void setTop(
int top) {this.top =
top;}public void setWidth(
int width) {this.width =
width;}public void setHeight(
int height) {this.height =
height;}@Overridepublic String toString() {return "TRect{" +
"left=" + left +
", top=" + top +
", width=" + width +
", height=" + height +
'}';}
} 圖片控件:TScallImageView
- 該控件可以xml中創建也可代碼創建,不過在調用其showImageToWindow()方法之前,需設置一下幾個屬性值:其中imageId及imageIds可以是圖片URL也可以是圖片id值。
public ViewGroup ninePlaceGridView;
//外部設置public Object imageId;
//外部設置public List<Object> imageIds;
//外部設置public int currentIndex;
//外部設置 package com.tikeyc.tnineplacegridviewlibrary.TNinePlaceGridView;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;import java.util.ArrayList;
import java.util.List;/*** Created by public1 on 2017/5/19.*/public class TScallImageView extends android.support.v7.widget.AppCompatImageView {public static final
int STATE_NORMAL =
0;public static final
int STATE_TRANSFORM_IN =
1;public static final
int STATE_TRANSFORM_OUT =
2;public ViewGroup ninePlaceGridView;
//外部設置private TRect originalRect;
//得到的第一個圖片相對于window的位置private List<TRect> originalRects;
//得到的第所有圖片相對于window的位置public Object imageId;
//外部設置public List<Object> imageIds;
//外部設置public int currentIndex;
//外部設置public TImageListBgView imageListBgView;public TScallImageView(Context context) {super(context);init();}public TScallImageView(Context context, AttributeSet attrs) {super(context, attrs);init();}public TScallImageView(Context context, AttributeSet attrs,
int defStyle) {super(context, attrs, defStyle);init();}private void init() {setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View view) {showImageToWindow();}});}/**獲取每個圖片相對于window的位置* @return*/private List<TRect>
getOriginalRects() {List<TRect> originalRects =
new ArrayList<TRect>
();int count =
ninePlaceGridView.getChildCount();for (
int i =
0; i < count; i++
) {if (ninePlaceGridView.getChildAt(i) instanceof TScallImageView) {TScallImageView scallImageView =
(TScallImageView) ninePlaceGridView.getChildAt(i);int[] outLocation =
new int[
2];scallImageView.getLocationInWindow(outLocation);Log.e("TAG",
"outLocation[0]:" + outLocation[
0] +
"outLocation[1]:" + outLocation[
1]);TRect tRect =
new TRect(outLocation[
0],outLocation[
1],scallImageView.getWidth(),scallImageView.getHeight());originalRects.add(tRect);} else {continue;}}this.originalRects =
originalRects;return originalRects;}public void showImageToWindow() {int[] outLocation =
new int[
2];getLocationInWindow(outLocation);
// originalRect = new TRect(getLeft(),getTop(),getWidth(),getHeight());
// originalRect = new TRect(outLocation[0],outLocation[1] - TKCUtils.getStatusBarHeight(getContext()),getWidth(),getHeight());originalRect =
new TRect(outLocation[
0],outLocation[
1],getWidth(),getHeight());imageListBgView =
new TImageListBgView(getContext(),originalRect,
this.imageId,
this.imageIds,currentIndex);imageListBgView.imageId =
imageId;imageListBgView.originalRects =
getOriginalRects();imageListBgView.startTransform(TScallImageView.STATE_TRANSFORM_IN);}} TImageListBgView:圖片放大縮小動畫,橫向滑動瀏覽等邏輯處理類
- 點擊手機的返回按鍵,縮小圖片:這里需要注意一點,在window上添加視圖后點擊手機的返回按鍵,不會響應當前的Activity,因此需要在添加在window上的視圖TImageListBgView內重寫public boolean dispatchKeyEvent(KeyEvent event)方法來實現:
/**因此View添加在Window,點擊手機返回按鈕無法響應,* 重寫此方法可以處理點擊手機返回的邏輯處理,縮小圖片到原位置* @param event* @return*/@Overridepublic boolean dispatchKeyEvent(KeyEvent
event) {
//2-4if (
event.getKeyCode() ==
KeyEvent.KEYCODE_BACK) {if (mState ==
TScallImageView.STATE_TRANSFORM_IN) {startTransform(TScallImageView.STATE_TRANSFORM_OUT);return true;}}return super.dispatchKeyEvent(
event);} package com.tikeyc.tnineplacegridviewlibrary.TNinePlaceGridView;import android.animation.Animator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;import com.squareup.picasso.Picasso;import java.util.List;/*** Created by public1 on 2017/5/23.*/public class TImageListBgView extends RelativeLayout {public int mState =
TScallImageView.STATE_NORMAL;private TRect originalRect;public List<TRect>
originalRects;public Object imageId;public List<Object>
imageIds;public int currentIndex;private ImageView animationIV;private LinearLayout gridViewBgView;private GridView gridView;private TPageHorizatalScrollView horizontalScrollView;private TPageControl pageControl;public TImageListBgView(Context context, TRect originalRect,Object imageId,List<Object> imageIds,
int currentIndex) {super(context);this.originalRect =
originalRect;this.imageId =
imageId;this.imageIds =
imageIds;this.currentIndex =
currentIndex;setBackgroundColor(Color.TRANSPARENT);initSubViews();}public TImageListBgView(Context context) {super(context);}public TImageListBgView(Context context, AttributeSet attrs) {super(context, attrs);}public TImageListBgView(Context context, AttributeSet attrs,
int defStyleAttr) {super(context, attrs, defStyleAttr);}/**因此View添加在Window,點擊手機返回按鈕無法響應,* 重寫此方法可以處理點擊手機返回的邏輯處理,縮小圖片到原位置* @param event* @return*/@Overridepublic boolean dispatchKeyEvent(KeyEvent
event) {
//2-4if (
event.getKeyCode() ==
KeyEvent.KEYCODE_BACK) {if (mState ==
TScallImageView.STATE_TRANSFORM_IN) {startTransform(TScallImageView.STATE_TRANSFORM_OUT);return true;}}return super.dispatchKeyEvent(
event);}@Overridepublic boolean dispatchKeyEventPreIme(KeyEvent
event) {
//1-3return super.dispatchKeyEventPreIme(
event);}private WindowManager windowManager;private void initSubViews() {//
initImageListBgView();//
initAnimationIV();//
initHorizontalScrollView();//
initGridView();//
initPageControl();}private void initImageListBgView() {Activity activity =
(Activity) getContext();windowManager =
activity.getWindowManager();WindowManager.LayoutParams layoutParams =
new WindowManager.LayoutParams();layoutParams.width =
TRect.getScreenWidth(getContext());layoutParams.height =
TRect.getScreenHeight(getContext());//FLAG_LAYOUT_IN_SCREENlayoutParams.flags =
WindowManager.LayoutParams.FLAG_FULLSCREEN;layoutParams.format = PixelFormat.RGBA_8888;
//讓背景透明,放大過程可以看到當前界面layoutParams.verticalMargin =
0;windowManager.addView(this,layoutParams);}private void initAnimationIV() {animationIV =
new ImageView(getContext());
// imageView.setBackgroundColor(Color.RED);
animationIV.setScaleType(ImageView.ScaleType.FIT_CENTER);LayoutParams params =
new LayoutParams(originalRect.getWidth(),originalRect.getHeight());params.leftMargin =
originalRect.getLeft();params.topMargin =
originalRect.getTop();addView(animationIV,params);
// Picasso.with(getContext()).load("http://ww2.sinaimg.cn/mw690/9e6995c9gw1f2uu70bzohj209q06g3yw.jpg").into(animationIV);if (imageId instanceof Integer) {animationIV.setImageResource((Integer) imageId);} else {Picasso.with(getContext()).load((String) imageId).into(animationIV);}}private void initHorizontalScrollView() {horizontalScrollView =
new TPageHorizatalScrollView(getContext());LayoutParams hsLayoutParams =
new LayoutParams(TRect.getScreenWidth(getContext()),TRect.getScreenHeight(getContext()));hsLayoutParams.leftMargin =
0;hsLayoutParams.topMargin =
0;addView(horizontalScrollView,hsLayoutParams);horizontalScrollView.mBaseScrollX = currentIndex*
TRect.getScreenWidth(getContext());horizontalScrollView.setOnScrollToIndexListen(new TPageHorizatalScrollView.OnScrollToIndexListen() {@Overridepublic void scrollToIndex(
int index) {currentIndex =
index;if (currentIndex >=
imageIds.size()){currentIndex = imageIds.size() -
1;} else if (currentIndex <
0) {currentIndex =
0;}Log.e("TAG",
"currentIndex" +
currentIndex);if (imageId instanceof Integer) {animationIV.setImageResource((Integer) imageIds.get(currentIndex));} else {Picasso.with(getContext()).load((String) imageIds.get(currentIndex)).into(animationIV);}originalRect = originalRects.
get(currentIndex);pageControl.setCurrentPage(currentIndex);}});int numColumns =
imageIds.size();gridViewBgView =
new LinearLayout(getContext());LinearLayout.LayoutParams testParams =
new LinearLayout.LayoutParams(TRect.getScreenWidth(getContext())*
numColumns,TRect.getScreenHeight(getContext()));horizontalScrollView.addView(gridViewBgView,testParams);}private void initGridView() {int numColumns =
imageIds.size();//
gridView =
new GridView(getContext());gridView.setNumColumns(numColumns);gridView.setColumnWidth(TRect.getScreenWidth(getContext()));LinearLayout.LayoutParams gridViewLayoutParams =
new LinearLayout.LayoutParams(TRect.getScreenWidth(getContext())*
numColumns,TRect.getScreenHeight(getContext()));gridViewLayoutParams.leftMargin =
0;gridViewLayoutParams.topMargin =
0;gridViewBgView.addView(gridView,gridViewLayoutParams);final TImageGridViewAdapter adapter =
new TImageGridViewAdapter(getContext());adapter.imageIds =
this.imageIds;gridView.setAdapter(adapter);adapter.setOnItemClickListener(new TImageGridViewAdapter.OnItemClickListener() {@Overridepublic void onItemClick(
int i, View view) {startTransform(TScallImageView.STATE_TRANSFORM_OUT);}});// gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
// @Override
// public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
// startTransform(TScallImageView.STATE_TRANSFORM_OUT);
// }
// });
}private void initPageControl() {pageControl =
new TPageControl(getContext(),
null);pageControl.setPageNumber(imageIds.size());pageControl.setSelectedColor(Color.RED);LayoutParams layoutParams =
new LayoutParams(TRect.getScreenWidth(getContext()),
40);layoutParams.topMargin = TRect.getScreenHeight(getContext()) -
100;addView(pageControl,layoutParams);}/**放大縮小動畫* @param state*/public void startTransform(final
int state) {final int duration =
300;ValueAnimator valueAnimator =
new ValueAnimator();valueAnimator.setDuration(duration);valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());if (state ==
TScallImageView.STATE_TRANSFORM_IN) {setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);mState =
TScallImageView.STATE_TRANSFORM_IN;gridViewBgView.setVisibility(INVISIBLE);pageControl.setVisibility(INVISIBLE);
// PropertyValuesHolder scaleHolder = PropertyValuesHolder.ofFloat("scale", mTransfrom.startScale, mTransfrom.endScale);PropertyValuesHolder leftHolder = PropertyValuesHolder.ofFloat(
"left",originalRect.getLeft(),
0);PropertyValuesHolder topHolder = PropertyValuesHolder.ofFloat(
"top", originalRect.getTop(),
0);PropertyValuesHolder widthHolder = PropertyValuesHolder.ofFloat(
"width", originalRect.getWidth(), TRect.getScreenWidth(getContext()));PropertyValuesHolder heightHolder = PropertyValuesHolder.ofFloat(
"height", originalRect.getHeight(), TRect.getScreenHeight(getContext()));PropertyValuesHolder alphaHolder = PropertyValuesHolder.ofInt(
"alpha",
0,
255);valueAnimator.setValues(leftHolder, topHolder, widthHolder, heightHolder, alphaHolder);} else {
// setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);
gridViewBgView.setVisibility(INVISIBLE);pageControl.setVisibility(INVISIBLE);animationIV.setVisibility(VISIBLE);setBackgroundColor(Color.TRANSPARENT);mState =
TScallImageView.STATE_TRANSFORM_OUT;
// PropertyValuesHolder scaleHolder = PropertyValuesHolder.ofFloat("scale", mTransfrom.endScale, mTransfrom.startScale);PropertyValuesHolder leftHolder = PropertyValuesHolder.ofFloat(
"left", animationIV.getLeft(), originalRect.getLeft());PropertyValuesHolder topHolder = PropertyValuesHolder.ofFloat(
"top", animationIV.getTop(), originalRect.getTop());PropertyValuesHolder widthHolder = PropertyValuesHolder.ofFloat(
"width", animationIV.getWidth(), originalRect.getWidth());PropertyValuesHolder heightHolder = PropertyValuesHolder.ofFloat(
"height", animationIV.getHeight(), originalRect.getHeight());PropertyValuesHolder alphaHolder = PropertyValuesHolder.ofInt(
"alpha",
255,
0);valueAnimator.setValues(leftHolder, topHolder, widthHolder, heightHolder, alphaHolder);// Handler handler = new Handler(){
// @Override
// public void handleMessage(Message msg) {
// super.handleMessage(msg);
// animationIV.setScaleType(ImageView.ScaleType.CENTER_CROP);//根據九宮格中的圖片的顯示模式設置
// }
// };
// handler.sendEmptyMessageDelayed(0,duration*9/10);
}valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic synchronized
void onAnimationUpdate(ValueAnimator animation) {// mTransfrom.scale = (Float) animation.getAnimatedValue("scale");Float left = (Float) animation.getAnimatedValue(
"left");Float top = (Float) animation.getAnimatedValue(
"top");Float width = (Float) animation.getAnimatedValue(
"width");Float height = (Float) animation.getAnimatedValue(
"height");Integer mBgAlpha = (Integer) animation.getAnimatedValue(
"alpha");LayoutParams layoutParams =
new LayoutParams(width.intValue(),height.intValue());layoutParams.leftMargin =
left.intValue();layoutParams.topMargin =
top.intValue();animationIV.setLayoutParams(layoutParams);setAlpha(mBgAlpha);}});final TImageListBgView[] imageListBgView = {
this};valueAnimator.addListener(new ValueAnimator.AnimatorListener() {@Overridepublic void onAnimationStart(Animator animation) {}@Overridepublic void onAnimationRepeat(Animator animation) {}@Overridepublic void onAnimationEnd(Animator animation) {/** 如果是進入的話,當然是希望最后停留在center_crop的區域。但是如果是out的話,就不應該是center_crop的位置了* , 而應該是最后變化的位置,因為當out的時候結束時,不回復視圖是Normal,要不然會有一個突然閃動回去的bug*/// TODO 這個可以根據實際需求來修改if (mState ==
TScallImageView.STATE_TRANSFORM_IN) {horizontalScrollView.baseSmoothScrollTo(0);setBackgroundColor(Color.BLACK);pageControl.setVisibility(VISIBLE);Handler handler =
new Handler(){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);gridViewBgView.setVisibility(VISIBLE);animationIV.setVisibility(INVISIBLE);}};handler.sendEmptyMessageDelayed(0, duration);} else if (mState ==
TScallImageView.STATE_TRANSFORM_OUT) {gridViewBgView.removeView(gridView);gridView =
null;horizontalScrollView.removeView(gridViewBgView);gridViewBgView =
null;removeView(animationIV);animationIV =
null;removeView(pageControl);pageControl =
null;windowManager.removeView(imageListBgView[0]);imageListBgView[0] =
null;}}@Overridepublic void onAnimationCancel(Animator animation) {}});valueAnimator.start();}} 如何使用,非常之簡單
- List<List<Object>> imageNames2D =
new ArrayList<List<Object>>
();List<Object> imageNames =
new ArrayList<Object>
();imageNames2D.add(imageNames);imageNames.add(Object);
- TNinePlaceGridView ninePlaceGridView =
(TNinePlaceGridView) view.findViewById(R.id.ninePlaceGridView);
- ninePlaceGridView.setImageNames(imageNames);
如下代碼示例:
public class MainActivity extends AppCompatActivity {@ViewInject(R.id.listView)private ListView listView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);x.view().inject(this);init();}private void init() {List<List<Object>> imageNames2D =
new ArrayList<List<Object>>
();for (
int i =
0; i <
30; i++
) {ArrayList<Object> imageNames =
new ArrayList<Object>
();Random random =
new Random();for (
int j =
0; j <= random.nextInt(
8); j++
) {if (j%
2 ==
0) {imageNames.add(R.mipmap.beauty);
// imageNames.add("http://7xi8d6.com1.z0.glb.clouddn.com/20171011084856_0YQ0jN_joanne_722_11_10_2017_8_39_5_505.jpeg");}
else {imageNames.add(R.mipmap.glenceluanch);
// imageNames.add("http://7xi8d6.com1.z0.glb.clouddn.com/2017-10-10-sakura.gun_10_10_2017_12_33_34_751.jpg");
}}imageNames2D.add(imageNames);}ListViewAdapter listViewAdapter =
new ListViewAdapter(
this);listViewAdapter.imageNames2D =
imageNames2D;listView.setAdapter(listViewAdapter);}@Overrideprotected void onResume() {super.onResume();}@Overrideprotected void onPause() {super.onPause();}@Overrideprotected void onDestroy() {super.onDestroy();}private class ListViewAdapter extends BaseAdapter {private Context context;public List<List<Object>>
imageNames2D;public ListViewAdapter(Context context) {this.context =
context;}@Overridepublic int getCount() {if (imageNames2D !=
null)
return imageNames2D.size();return 0;}@Overridepublic Object getItem(
int i) {return null;}@Overridepublic long getItemId(
int i) {return 0;}private class ViewHelper {CircleImageView imageViewIcon;TextView textViewNickName;TNinePlaceGridView ninePlaceGridView;}@Overridepublic View getView(
int i, View view, ViewGroup viewGroup) {ViewHelper viewHelper;if (view ==
null) {view = View.inflate(context,R.layout.timage_listactivity_listview_item,
null);viewHelper =
new ViewHelper();viewHelper.imageViewIcon =
(CircleImageView) view.findViewById(R.id.imageViewIcon);viewHelper.textViewNickName =
(TextView) view.findViewById(R.id.textViewNickName);viewHelper.ninePlaceGridView =
(TNinePlaceGridView) view.findViewById(R.id.ninePlaceGridView);view.setTag(viewHelper);} else {viewHelper =
(ViewHelper) view.getTag();}List<Object> imageNames =
this.imageNames2D.
get(i);viewHelper.ninePlaceGridView.setImageNames(imageNames);return view;}}} ?
總結
以上是生活随笔為你收集整理的Android 实现九宫格、点击图片放大全屏浏览等的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。