編輯:關於Android編程
private class ImageAdapter extends PagerAdapter{ private ArrayListviewlist; public ImageAdapter(ArrayList viewlist) { this.viewlist = viewlist; } @Override public int getCount() { //設置成最大,使用戶看不到邊界,大家可以去查詢下這個大小 return Integer.MAX_VALUE; } @Override public void destroyItem(ViewGroup container, int position, Object object) { //注:不要在這裡調用removeView } @Override public Object instantiateItem(ViewGroup container, int position) { //對ViewPager頁號求模取出View列表中要顯示的項 position %= viewlist.size(); if (position<0){ position = viewlist.size()+position; } //這裡是view ViewHolder viewHolder = null; View view = LayoutInflater.from(mContext).inflate( R.layout.item_finefare_layout, null); if (viewHolder == null) { viewHolder = new ViewHolder(view); } bindView(viewHolder, data); container.addView(view, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); return view; } }
上面代碼應該注意的幾點:
getCount()方法的返回值:這個值直接關系到ViewPager的“邊界”,因此當我們把它設置為Integer.MAX_VALUE之後,用戶基本就看不到這個邊界了(估計滑到這裡的時候電池已經掛了吧o_O)。當然,通常情況下設置為100倍實際內容個數也是可以的,之前看的某個實現就是這麼干的。
instantiateItem()方法position的處理:由於我們設置了count為Integer.MAX_VALUE,因此這個position的取值范圍很大很大,但我們實際要顯示的內容肯定沒這麼多(往往只有幾項),所以這裡肯定會有求模操作。但是,簡單的求模會出現問題:考慮用戶向左滑的情形,則position可能會出現負值。所以我們需要對負值再處理一次,使其落在正確的區間內。
instantiateItem()方法父組件的處理:通常我們會直接addView,但這裡如果直接這樣寫,則會拋出IllegalStateException。假設一共有三個view,則當用戶滑到第四個的時候就會觸發這個異常,原因是我們試圖把一個有父組件的View添加到另一個組件。
經過上面的解釋,我們已經很清楚了,以下是代碼的詳細實現,數據來源於網上,大家可以自行模擬:public class WelfareAdapter extends PagerAdapter { private Context mContext; private List用到的布局:dataList = new ArrayList<>(); public WelfareAdapter(Context mContext) { this.mContext = mContext; } public void setDatas(List list) { if (list.size() <= 0) { dataList.clear(); notifyDataSetChanged(); return; } dataList.clear(); dataList.addAll(list); notifyDataSetChanged(); } @Override public int getCount() { return Integer.MAX_VALUE; } @Override public int getItemPosition(Object object) { return POSITION_NONE; } @Override public Object instantiateItem(ViewGroup container, int position) { position %= dataList.size(); if (position<0){ position = dataList.size()+position; } PanicBean data = dataList.get(position); ViewHolder viewHolder = null; View view = LayoutInflater.from(mContext).inflate( R.layout.item_finefare_layout, null); if (viewHolder == null) { viewHolder = new ViewHolder(view); } bindView(viewHolder, data); container.addView(view, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); return view; } private void bindView(ViewHolder viewholder, final PanicBean data) { Glide.with(mContext).load(data.pic).into(viewholder.welfareImage); viewholder.welfareImage.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { ToastUtils.showToast("你點擊了"+data.href); } }); } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public void destroyItem(ViewGroup container, int position, Object object) { // container.removeView((View) object); } class ViewHolder { @BindView(R.id.welfare_image) RoundedImageView welfareImage; ViewHolder(View view) { ButterKnife.bind(this, view); view.setTag(this); } public void reset() { welfareImage.setBackground(mContext.getResources().getDrawable(R.drawable.welfare_default_icon)); } } }
public class FineFareEntity { public List為了方便使用我們都自定義成View,方便以後代碼維護:panic; public static class PanicBean { public String id; public long endtime; public String pic; public int type; public String href; public String title; public String share; } }
public class WelfareView extends SimpleLinearLayout { @BindView(R.id.finefare_count) TextView finefareCount; @BindView(R.id.viewPager) ViewPager viewPager; @BindView(R.id.finefare_name) TextView finefareName; @BindView(R.id.welfare_view) LinearLayout welfareView; private WelfareAdapter adapter = null; private List這裡有一個滑動縮放的類:welfareList = null; public WelfareView(Context context) { super(context); } public WelfareView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void initViews() { contentView = inflate(mContext, R.layout.layout_welfare, this); ButterKnife.bind(this); initViewPager(); initTouch(); } private void initTouch() { //這裡要把父類的touch事件傳給子類,不然邊上的會滑不動 setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return viewPager.dispatchTouchEvent(event); } }); viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { position %= welfareList.size(); if (position<0){ position = welfareList.size()+position; } finefareName.setText(welfareList.get(position).id); } @Override public void onPageScrollStateChanged(int state) { } }); } private void initViewPager() { viewPager.setOffscreenPageLimit(3); viewPager.setPageTransformer(true, new ScalePagerTransformer()); //設置Pager之間的間距 viewPager.setPageMargin(UIUtils.dp2px(mContext, 15)); adapter = new WelfareAdapter(mContext); viewPager.setAdapter(adapter); } public void setWelfareData(List datas) { this.welfareList = datas; welfareView.setVisibility(datas.size()>0?VISIBLE:GONE); finefareCount.setText("共有" + datas.size() + "個福利"); finefareName.setText(welfareList.get(getCurrentDisplayItem()).title); adapter = new WelfareAdapter(mContext); adapter.setDatas(datas); viewPager.setAdapter(adapter); viewPager.setCurrentItem(adapter.getCount() > 0 ? 1 : 0, true); } public int getCurrentDisplayItem() { if (viewPager != null) { return viewPager.getCurrentItem(); } return 0; } }
public class ScalePagerTransformer implements ViewPager.PageTransformer { private static final float MIN_SCALE = 0.85f; private static final float MIN_ALPHA = 0.5f; @Override public void transformPage(View view, float position) { if (position >= -1 || position <= 1) { final float height = view.getHeight(); final float width = view.getWidth(); final float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position)); final float vertMargin = height * (1 - scaleFactor) / 2; final float horzMargin = width * (1 - scaleFactor) / 2; view.setPivotY(0.5f * height); view.setPivotX(0.5f * width); if (position < 0) { view.setTranslationX(horzMargin - vertMargin / 2); } else { view.setTranslationX(-horzMargin + vertMargin / 2); } view.setScaleX(scaleFactor); view.setScaleY(scaleFactor); view.setAlpha(MIN_ALPHA + (scaleFactor - MIN_SCALE) / (1 - MIN_SCALE) * (1 - MIN_ALPHA)); } } }
SimpleLinearLayout 類
public class SimpleLinearLayout extends LinearLayout { protected Context mContext; protected View contentView; protected AtomicBoolean isPreparingData; public SimpleLinearLayout(Context context) { super(context); this.mContext = context; isPreparingData = new AtomicBoolean(false); initViews(); } public SimpleLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); this.mContext = context; isPreparingData = new AtomicBoolean(false); initViews(); } protected void initViews() { } }
android:clipChildren="false" android:layout_marginTop="10dp" android:background="@color/c12" android:orientation="vertical">
private void initWelfare() { String welfare = FileUtils.readAssert(getActivity(), "welfare.txt"); FineFareEntity entity=JsonUtils.parseJson(welfare,FineFareEntity.class); if (entity!=null){ welfareView.setWelfareData(entity.panic); } }涉及到的布局:
public static String readAssert(Context context, String fileName){ String resultString=""; try { InputStream inputStream=context.getResources().getAssets().open(fileName); byte[] buffer=new byte[inputStream.available()]; inputStream.read(buffer); resultString=new String(buffer,"utf-8"); } catch (Exception e) { e.printStackTrace(); } return resultString; }最後為了方便大家的模擬,我把數據給大家,有點多,大家自己放到assert目錄下,
{ panic: [ { id: "2412", endtime: 1472097600000, pic: "http://pc1.img.ymatou.com/G02/M04/E3/67/CgvUBVe9vyOAV47CAACXZZs5GrU558_o.jpg", type: 1, href: "http://evt.ymatou.com/n770", title: "今日限時搶", share: "" }, { id: "2417", endtime: 1472097600000, pic: "http://pc1.img.ymatou.com/G02/M09/E4/37/CgvUA1e91VmAMYrwAAC5qcblOUg650_o.jpg", type: 1, href: "http://evt.ymatou.com/n781", title: "今日限時搶", share: "" }, { id: "2413", endtime: 1472097600000, pic: "http://pc1.img.ymatou.com/G02/M05/E3/D4/CgvUA1e9v2SAVf3qAAB9GcBIWYA268_o.jpg", type: 1, href: "http://evt.ymatou.com/n771", title: "今日限時搶", share: "" }, { id: "2414", endtime: 1472097600000, pic: "http://pc1.img.ymatou.com/G02/M05/E3/69/CgvUBVe9v4aAMaFRAABWy73vn2g252_o.jpg", type: 1, href: "http://evt.ymatou.com/n772", title: "今日限時搶", share: "" }, { id: "2415", endtime: 1472097600000, pic: "http://pc1.img.ymatou.com/G02/M06/E3/02/CgvUBFe9v6WAP85NAAC6EK5e5Vg469_o.jpg", type: 1, href: "http://evt.ymatou.com/n773", title: "今日限時搶", share: "" }, { id: "2416", endtime: 1472097600000, pic: "http://pc1.img.ymatou.com/G02/M06/E3/02/CgvUBFe9v8CAHyXVAACELcKFT_M328_o.jpg", type: 1, href: "http://evt.ymatou.com/n775", title: "今日限時搶", share: "" } ] }
引言:去年Android 6.0發布後,其新引入的(Requesting Permissions at Run Time)運行時權限就備受開發者關注,隨著今年國內手機廠商
為什麼要寫這篇博客呢?因為,我在做這個第三方登錄的時候,找了很多資料,發現要麼就是過時了,要麼就是說的很不清楚,很羅嗦,而且很多都是一些小demo,不是什麼實例,甚至連騰
ActionBar是3.0後的UI設計規范,同時也是Google極力推薦使用的設計風格,如何快速設計一個入眼的ActionBar呢,更進一步,給我們搭好一個入眼的Acti
這次是列表滑動刪除的第三波,仿微信的列表滑動刪除。先上個效果圖: 前面的文章裡面說過開源框架SwipeListView的實現原理是每個列表item中