??項(xiàng)目中一個(gè)展示圖片數(shù)據(jù)的地方玉控,原本的廣告是在圖片上方的,然后被要求將廣告放到圖片中間狮惜。因?yàn)閺V告是有高度的高诺,所以首先是想將圖片切割成上下兩塊,然后將廣告上到中間碾篡。
??切割圖片發(fā)現(xiàn)網(wǎng)上有一種很簡(jiǎn)單的方法虱而,你想切成幾塊就切成幾塊,幾行代碼的事兒开泽,主要用到了Bitmap的一個(gè)靜態(tài)方法牡拇,這個(gè)方法可以讓你從指定位置開始截取指定寬高的的圖片。
@param xValue 起始x坐標(biāo)
@param yValue 起始y坐標(biāo)
@param pieceWidth 要裁剪的圖的寬度
@param pieceHeight 要裁剪的圖的寬度
Bitmap.createBitmap(bitmap, xValue, yValue,pieceWidth, pieceHeight)
??中間一刀切無非就是(0,1/2h,w,1/2h),有點(diǎn)像String.subString()惠呼,其實(shí)圖片在內(nèi)存中就是用一個(gè)二維數(shù)據(jù)來保存的导俘。然后將切割后的圖片展示到界面上正美滋滋的時(shí)候老板說這不行啊,要是剛好切到了字那不就看不清了剔蹋,于是將參數(shù)一改趟畏,中間重疊一部分就可以了。
int width = bitmap.getWidth();
int height = bitmap.getHeight();
//碎片的寬高是一樣的和原圖片相同滩租。
int splitedWidth = width;
//高度稍微加一點(diǎn)。
int splitedHeight = height/2+overlapping;
//第一片
Bitmap top = Bitmap.createBitmap(bitmap, 0, 0,splitedWidth, splitedHeight);
//第二片 起始位置有變化了 為一半的高度還要減去重疊高度
Bitmap bottom = Bitmap.createBitmap(bitmap, 0, 1/2*height-overlapping,splitedWidth, splitedHeight);
??這樣發(fā)現(xiàn)圖片就切割完成了利朵。
??圖片切割完了后突然發(fā)現(xiàn)律想,臥槽這樣不行啊,因?yàn)槿绻菍V告放到頁面绍弟,每次頁面切換(ViewPager)的時(shí)候廣告就會(huì)重新加載技即,這不sb了嘛。
??想了半天樟遣,也沒想到什么比較優(yōu)的解決方案而叼,只能在Activity的布局中搞一個(gè)顯示廣告的布局(正中間)和ViewPager用FrameLayout一起套著,然后在ViewPager的Item布局中同樣的位置放一塊View將上下兩個(gè)ImageView分開來豹悬,產(chǎn)生廣告是鑲嵌在圖片中的假象葵陵,不過一翻頁就暴露了。
??不過這也會(huì)有問題瞻佛,當(dāng)圖片過小的時(shí)圖片就會(huì)在所擁有的空白地方居中顯示脱篙,然后圖片和廣告之間有很大的縫隙,所以就在ImageView的外面套一層RelativeLayout伤柄,然后將ImageView設(shè)置為與父容器底部對(duì)齊绊困,這樣就差不多上下兩塊圖片都緊挨著廣告了。
//layout_acitivity
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ViewPager
android:layout_gravity="center_vertical"
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<FrameLayout
android:id="@+id/adContainer"
android:layout_gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</FrameLayout>
</FrameLayout>
//item_viewpager
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_white">
<!--用來展示完整圖片 默認(rèn)是有加載廣告的 所以這個(gè)默認(rèn)不可見-->
<LinearLayout
android:id="@+id/ll_full"
android:visibility="gone"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/iv"
android:scaleType="centerCrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
<!--這個(gè)是用來展示兩半的圖片的代碼-->
<LinearLayout
android:id="@+id/ll_splite"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="0dp">
<ImageView
android:layout_alignParentBottom="true"
android:id="@+id/top"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
<FrameLayout
android:id="@+id/adContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</FrameLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="0dp">
<ImageView
android:layout_alignParentTop="true"
android:id="@+id/bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
</LinearLayout>
</FrameLayout>
??用戶將廣告關(guān)閉了后就需要將未切割的圖片展示出來适刀,我這使用了一個(gè)笨辦法秤朗,就是將兩個(gè)小IV和一個(gè)大IV用一個(gè)FrameLayout來包裹起來,默認(rèn)顯示兩個(gè)分割后的圖片笔喉。
??當(dāng)用戶關(guān)閉了廣告后就需要將小IV隱藏掉取视,讓大IV顯示出來。但是這里又有問題了常挚,原生的ViewPager會(huì)緩存3個(gè)頁面(數(shù)據(jù)不太嚴(yán)謹(jǐn))贫途,所以當(dāng)顯示第一個(gè)頁面時(shí)會(huì)預(yù)加載第二個(gè)頁面,這樣預(yù)加載的也是切割后的圖片(Adapter中用一個(gè)標(biāo)記來記錄是否切割)待侵,所以當(dāng)用戶在第一個(gè)頁面關(guān)閉了廣告的時(shí)候丢早,當(dāng)前頁面中間還會(huì)在相同位置留下一個(gè)廣告大小空白區(qū)域。而且用戶翻到第二頁的時(shí)候會(huì)發(fā)現(xiàn)中間還是有個(gè)空白區(qū)域。參考ListView或者RecyclerView怨酝,調(diào)用ViewPager的Adapter的notifyDataSetChanged方法發(fā)現(xiàn)沒個(gè)卵用傀缩,看下方法源碼發(fā)現(xiàn)getItemPosition這個(gè)方法默認(rèn)返回POSITION_UNCHANGED,這就意味著默認(rèn)情況下系統(tǒng)是認(rèn)為數(shù)據(jù)無變化的所以不會(huì)刷新农猬。于是就重寫這個(gè)方法赡艰,直接返回POSITION_NONE。因?yàn)槲覀儎偤眯枰⑿滤幸呀?jīng)緩存了的數(shù)據(jù)斤葱。
@Override
public int getItemPosition(Object obj){
return POSITION_NONE;
}
??如果我們只需要刷新當(dāng)前頁面慷垮,可以給View添加tag。
??在instantiateItem()方法中給當(dāng)前頁面添加一個(gè)tag(當(dāng)前頁面數(shù),int)揍堕,然后在getItemPosition判斷當(dāng)參數(shù)的tag是不是當(dāng)前頁的index料身,如果是說明是當(dāng)前頁,如果不是說明是緩存頁衩茸。
@Override
public Object instantiateItem(ViewGroup container, final int position) {
View view = LayoutInflater.from(mContext).inflate(R.layout.ids, container,false);
view.setTag(position);
}
@Override
public int getItemPosition(Object obj){
//當(dāng)前頁需要刷新
if(mCurrentPageIndex == (int)(View(obj)).getTag()){
return POSITION_NONE;
}
//其他緩存頁面不需要刷新
return POSITION_UNCHANGED;
}