RecyclerView高仿IOS照片瀑布流式展示圖片效果
摘要:
蘋果有自己的元件能夠很快捷方便的實現這種類似瀑布流但是比瀑布流更為複雜的照片展示效果,當時接到這個需求時我也是一臉懵逼,而且查閱很多資料以及請教一些同行都沒有找到更好的idea,以此在與同事共同商討之下最終確立設計方式,此佈局能夠自動根據圖片大小進行智慧尋找更合適的方格展示,以此達到IOS這種展示效果。
佈局效果:
最終效果:
核心程式碼:
public class PhotoMomentDetailAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private float mSideMargin; private int ITEM_TYPE_HEADER = 0; private int ITEM_TYPE_CONTENT_GRID = 1; private int ITEM_TYPE_FOOTER = 2; private static final int ITEM_TYPE_CONTENT_LIST0 = 3; private static final int ITEM_TYPE_CONTENT_LIST1 = 4; private static final int ITEM_TYPE_CONTENT_LIST2 = 5; private static final int ITEM_TYPE_CONTENT_LIST3 = 6; private static final int ITEM_TYPE_CONTENT_LIST4 = 7; private static final int ITEM_TYPE_CONTENT_LIST5 = 8; private static final int ITEM_TYPE_CONTENT_LIST6 = 9; private static final int ITEM_TYPE_CONTENT_LIST7 = 10; private static final int ITEM_TYPE_CONTENT_LIST8 = 11; private static final int ITEM_TYPE_CONTENT_LIST9 = 12; private static final int ITEM_TYPE_CONTENT_LIST10 = 13; private int mScreenWidth; private RecyclerView mRecyclerView; private ArrayList<View> mHeaderViews = new ArrayList<View>(); private ArrayList<View> mFooterViews = new ArrayList<View>(); private ArrayList<Integer> mItemList =new ArrayList<>(); private MomentDetailBean mData; //瞬間詳情資料來源 /**未分組圖片資料列表,用於預覽*/ private ArrayList<ImagesModel> mSourcePhotoList = new ArrayList<ImagesModel>(); /**選擇的資料項path列表*/ private HashMap<String, ImagesModel> mSelectedMap = new HashMap<String, ImagesModel>(); /**是否為編輯狀態*/ private boolean mIsEdit; private Context mContext; private int mMaxItemCount=25; private Random mRandom; private LayoutInflater mInflater; private int mPosition; private HashMap<Integer,Integer> mLayoutMap; private int mDataCount; private int mDataTotal; private LinkedHashMap<String,ImagesModel> mSourcePhotoMap = new LinkedHashMap<String,ImagesModel>(); private Handler uiHandler; private ImagesDataManager mImagesDataManager; private IUiGroupChangedListener mUiGroupChangedListener; private OnPhotoItemClickListener onItemClickListener; private boolean mIsShowEncryptImage; private String mSecretKey; private boolean mIsDataFromNet; private CXImageLoaderUtil mImageLoaderUtil; private DisplayImageOptions mPectanglePhotoOption; private DisplayImageOptions mPhotoOption; private boolean mClickShowBigImage=true; private ArrayList<ImgSearchGroup> mDistinguishGroup; private String mTitle; private ArrayList<NewPhotoBean> mBeforehandImgList; private ArrayList<NewPhotoBean> mPanoramagramList; public PhotoMomentDetailAdapter(String title,Context context, RecyclerView view,boolean isDataFromNet,IUiGroupChangedListener groupChangedListener, int screen, OnPhotoItemClickListener itemClickListener, Handler handler) { mTitle = title; mContext = context; mRecyclerView = view; mScreenWidth=screen; mRandom = new Random(); mInflater = LayoutInflater.from(mContext); mImagesDataManager = (ImagesDataManager) BusinessCenter.getDataManager(mContext, BusinessCenter.DataArea.SDCARD,ImagesDataManager.class); mImageLoaderUtil = CXImageLoaderUtil.getInstance(mContext); mPectanglePhotoOption = DisplayImageOptionsFactory.rectanglesHrinkDisplayImageOptions(); mPhotoOption = DisplayImageOptionsFactory.shrinkDisplayImageOptions(); mSideMargin = mContext.getResources().getDimension(R.dimen.img_listview_item_iv_space) * 2; mIsDataFromNet = isDataFromNet; mUiGroupChangedListener =groupChangedListener; onItemClickListener =itemClickListener; uiHandler = handler; init(); } public PhotoMomentDetailAdapter(Context context, ArrayList<ImgSearchGroup> distingyuishGroup, OnPhotoItemClickListener itemClickListener, RecyclerView view, int screen) { mContext = context; mRecyclerView = view; mScreenWidth=screen; mDistinguishGroup =distingyuishGroup; onItemClickListener =itemClickListener; mImageLoaderUtil = CXImageLoaderUtil.getInstance(mContext); mPectanglePhotoOption = DisplayImageOptionsFactory.rectanglesHrinkDisplayImageOptions(); mPhotoOption = DisplayImageOptionsFactory.shrinkDisplayImageOptions(); } /** *HashMap<Integer,Integer>, pararms1為layout的編號id,params2為layout子view數量 * mItemList每個資料與HashMap<Integer,Integer>中每個layout對映 */ private void init() { if (mLayoutMap==null){ mLayoutMap=new HashMap<>(); mLayoutMap.put(0,1); //一大 mLayoutMap.put(1,2); //三小 mLayoutMap.put(2,4); //一大二小 mLayoutMap.put(3,3); //二小一大 mLayoutMap.put(4,3); //一大一小 mLayoutMap.put(5,3); //三大 mLayoutMap.put(6,2); //一大三小 mLayoutMap.put(7,3); //二大 mLayoutMap.put(8,2); //兩小 mLayoutMap.put(9,1); //一大 mLayoutMap.put(10,1); //一大 } String title = CXPreferencesHelper.readString(mContext, mTitle, null); //控制同一個條目每次進去顯示同樣效果 if (title==null){ StringBuffer sb=new StringBuffer(); int[] arr={0,9,10}; //大圖佈局編號 while(mItemList.size()<mLayoutMap.size()-arr.length){ //1~8號佈局隨機排列 int itemId=mRandom.nextInt(mLayoutMap.size()-arr.length)+1; if (!mItemList.contains(itemId)){ mItemList.add(itemId); } } int j=0; while(mItemList.size()<mLayoutMap.size()&&j<arr.length){ //往排好的隨機佈局中見縫插針,不能連續插入,必須間隔 int i = mRandom.nextInt(mItemList.size()); if (i==0&&mItemList.get(i)!=0){ mItemList.add(i, arr[j++]); }else if (i==mItemList.size()-1&&mItemList.get(i)!=0){ mItemList.add(i+1, arr[j++]); //往後面加 }else if(mItemList.get(i)!=0&&mItemList.get(i-1)!=0) { mItemList.add(i, arr[j++]); } } for (int i = 0; i < mItemList.size(); i++) { if (i==0){ sb.append(mItemList.get(i)); }else{ sb.append("&"+mItemList.get(i) ); } } CXPreferencesHelper.saveString(mContext,mTitle,sb.toString()); }else{ String[] split = title.split("&"); for (String s : split) { mItemList.add(Integer.parseInt(s)); } } CXLog.d("bbbb",mItemList.toString()); } /** * 控制是否可以重新整理資料 */ public AtomicBoolean mCanRefresh = new AtomicBoolean(true); public void setDataList(MomentDetailBean data) { mData=data; mDataTotal=data.getImgList().size(); ArrayList<ImagesModel> imgList = data.getImgList(); if (mSourcePhotoMap!=null&&mSourcePhotoList!=null) { mSourcePhotoMap.clear(); mSourcePhotoList.clear(); for (int i = 0; i < imgList.size(); i++) { ImagesModel imagesModel = imgList.get(i); mSourcePhotoList.add(imagesModel); mSourcePhotoMap.put(imagesModel.getImgPath(), imagesModel); } } if (getLayoutManager() instanceof GridLayoutManager) { if (getColum() == 1) { beforehandLoadImg(mSourcePhotoList); } } notifyChanged(); } /** * 預載入圖片,只在實現照片牆時做預載入處理,目的在於篩選全景圖 * @param sourcePhotoList */ private void beforehandLoadImg(ArrayList<ImagesModel> sourcePhotoList) { if (mBeforehandImgList==null) { //非全景圖片集合 mBeforehandImgList = new ArrayList<>(); } if (mPanoramagramList==null) { //全景圖片集合 mPanoramagramList = new ArrayList<>(); } mBeforehandImgList.clear(); mPanoramagramList.clear(); int beforehandLoad=sourcePhotoList.size()>mMaxItemCount?mMaxItemCount:sourcePhotoList.size(); for (int i = 0; i <beforehandLoad ; i++) { Bitmap bitmap = mImageLoaderUtil.displayBitmap("file://"+sourcePhotoList.get(i) .thumbnailPath, mPectanglePhotoOption); //沒有縮圖就拿大圖 if (bitmap==null){ bitmap = mImageLoaderUtil.displayBitmap("file://"+sourcePhotoList.get(i) .getPath(), mPectanglePhotoOption); } CXLog.d("bbbb","file://"+sourcePhotoList.get(i).thumbnailPath+" file://"+sourcePhotoList.get(i).getPath()); if (bitmap!=null){ float width = bitmap.getWidth(); float height = bitmap.getHeight(); NewPhotoBean bean = new NewPhotoBean(); bean.index=i; bean.model=sourcePhotoList.get(i); bean.bitmap=bitmap; if ((width/height)>=4){ //全景圖規則 mPanoramagramList.add(bean); }else{ mBeforehandImgList.add(bean); } } } refreshDataList(); } /** * 將資料與佈局一一對應 */ private void refreshDataList() { mNewPhotoBeanList.clear(); mNewPhotoBeanList.addAll(mBeforehandImgList); if (mPanoramagramList!=null){ int j =0; ArrayList<NewPhotoBean> tempList =new ArrayList<>(); tempList.addAll(mPanoramagramList); for (int i = 0; i < mItemList.size(); i++) { int frontDataCount = getFrontDataCount(i+1); if ((mItemList.get(i)==0||mItemList.get(i)==9||mItemList.get(i)==10)&&j<mPanoramagramList.size()){ if (mNewPhotoBeanList.size()>frontDataCount) { mNewPhotoBeanList.add(frontDataCount, mPanoramagramList.get(j)); }else{ mNewPhotoBeanList.add(mNewPhotoBeanList.size(), mPanoramagramList.get(j)); } tempList.remove(mPanoramagramList.get(j++)); } } if (tempList!=null&&tempList.size()>0){ mNewPhotoBeanList.addAll(tempList); } mNewPhotoList.clear(); for (NewPhotoBean newPhotoBean : mNewPhotoBeanList) { mNewPhotoList.add(newPhotoBean.model); } } Log.d("dddd"," refreshDataList"+mNewPhotoBeanList.size()); } private class NewPhotoBean{ private int index; private ImagesModel model; private Bitmap bitmap; } public interface IUiGroupChangedListener { /** * 選擇變化通知UI改變 * @param size 選擇資料的總大小(容量) * @param isSelectedAll 是否全選 * @param selectedNum 選擇資料數量 * @param isSingle 是否為針對單個操作 * @param model 只有在針對單個進行選擇的情況下才有model!=null * @param isChecked 只有在針對單個進行選擇的情況下,選中true,取消選中false */ void selectChanged(long size, boolean isSelectedAll, long selectedNum, boolean isSingle, ImagesModel model, boolean isChecked,boolean isEdit); /** * 總資料個數變化 * @param count */ void dataCountChanged(int count); } public interface OnPhotoItemClickListener { /** * 單張圖片點選位置 * @param clickIndex */ void onItemClick(int clickIndex); } /** * 新增頭部View * * @param view */ public void addHeaderView(View view) { mHeaderViews.add(view); } /** * 新增底部View * * @param view */ public void addFooterView(View view) { mFooterViews.clear(); mFooterViews.add(view); } /** * 獲取內容數量 */ public int getContentCount() { if (getColum()==2){ return mDistinguishGroup == null ? 0 : mDistinguishGroup.size(); }else { return mData == null ? 0 : mData.getImgList().size(); } } /** * 獲取頭部View數量 * * @return */ public int getHeaderViewCount() { return mHeaderViews == null ? 0 : mHeaderViews.size(); } /** * 獲取底部View數量 * * @return */ public int getFooterViewCount() { return mFooterViews == null ? 0 : mFooterViews.size(); } /** * 移除頭部View * * @param view */ public void removeHeaderView(View view) { mHeaderViews.clear(); } /** * 移除頭部View */ public void removeFooterView() { mFooterViews.clear(); } /** * 判斷是否是頭部View */ public boolean isHeaderView(int position) { return getHeaderViewCount() != 0 && position < getHeaderViewCount(); } /** * 判斷是否是底部View */ public boolean isFooterView(int position) { return getFooterViewCount() != 0 && position >= getHeaderViewCount() + getContentCount(); } /** * 獲取recyrView的layoutManager */ private RecyclerView.LayoutManager getLayoutManager(){ RecyclerView.LayoutManager layoutManager = mRecyclerView.getLayoutManager(); return layoutManager; } /** * 獲取recyclerView列數 * @return * getColum==1為瞬間詳情摘要介面或getColum==3為瞬間詳情顯示全部頁面 * getColum==4時為瞬間人物、事物分類詳情頁面 */ private int getColum() { return ((GridLayoutManager) getLayoutManager()).getSpanCount(); } /** * 可顯示最大資料量 * @return */ public void setMaxItemCount(int count){ mMaxItemCount=count; } /**獲取選擇的map,最好不要修改該物件本身*/ public HashMap<String, ImagesModel> getSelectedMap() { return mSelectedMap; } /** * 獲取選擇的列表資訊 * @return */ public ArrayList<String> getSelectedList() { ArrayList<String> paths = new ArrayList<String>(); if(!mSelectedMap.isEmpty()){ Iterator<String> keys = mSelectedMap.keySet().iterator(); while (keys.hasNext()){ paths.add(keys.next()); } } return paths; } public void notifySelectChange() { sendUiSelectChanged(false, null, false); notifyDataSetChanged(); } public void notifyChanged(){ notifyDataSetChanged(); } /** * 只有在針對單個進行選中的情況下才有model!=null * @param model */ private void sendUiSelectChanged(boolean isSingle, ImagesModel model, boolean isChecked) { if(mUiGroupChangedListener != null) { mUiGroupChangedListener.selectChanged(0,isAllSelected(), mSelectedMap.size(), isSingle, model, isChecked, mIsEdit); } } /** * 是否選中 * * @param model * 物件 * @return 是否選中 */ public boolean isCheck(ImagesModel model) { return mSelectedMap.containsKey(model.getPath()); } public void setEditModel(boolean isEdit) { if(isEdit != mIsEdit) { setSelectAll(false); mIsEdit = isEdit; } notifyChanged(); } /** * 用於UI全選或取消全選 * @param isAllSelect */ public void setSelectAll(boolean isAllSelect) { if(mData != null) { mSelectedMap.clear(); if (isAllSelect) { for (ImagesModel model : mData.getImgList()) { mSelectedMap.put(model.getImgPath(), model); } } notifyChanged(); } } /** * 需要更新ui的 */ public void clearSelectDataNoUI(){ if(mSelectedMap!=null){ mSelectedMap.clear(); notifyChanged(); } } /** * 獲取用於可預覽的列表 * @return */ public ArrayList<ImagesModel> getDataList() { if (getLayoutManager() instanceof GridLayoutManager){ if (getColum()==1){ return mNewPhotoList; }else{ return mSourcePhotoList; } } return null; } public ArrayList<ImagesModel> getAllDataList() { return mSourcePhotoList; } /** * 刪除選擇的資料列表 * @param isDeletePath 是否刪除本地檔案 */ public void deleteSelectList(List<String> deleteList, boolean isDeletePath) { if (deleteList != null && mSourcePhotoMap != null) { Iterator<String> delIterator = deleteList.iterator(); while (delIterator.hasNext()) { String path = delIterator.next(); delete(path,isDeletePath); } } } /**會對引數進行修改*/ public void updateSelectListNoUI(List<String> selectList) { mSelectedMap.clear(); if(selectList!=null && !selectList.isEmpty()) { int len = selectList.size(); int count =0; if(mSourcePhotoList != null){ for (ImagesModel model : mSourcePhotoList) { Iterator<String> iterator = selectList.iterator(); while (iterator.hasNext()){ String sel = iterator.next(); if(sel.equals(model.getImgPath())){ mSelectedMap.put(sel, model); iterator.remove(); count++; if (count==len){ return; } break; } } } } } } /** * 刪除選擇的單個數據 * @param isDeletePath 是否刪除本地檔案 */ public void deleteSelectPath(String deletePath, boolean isDeletePath) { if (deletePath != null && mSourcePhotoMap != null) { final LinkedHashMap<String,ImagesModel> dataMap = new LinkedHashMap<String,ImagesModel>(); dataMap.putAll(mSourcePhotoMap); delete(deletePath,isDeletePath); } } public void removeSelectDataOnUI(HashMap<String, ImagesModel> deletedMap){ if(deletedMap.isEmpty()){ return; } Iterator<Map.Entry<String,ImagesModel>> iterator = deletedMap.entrySet().iterator(); while (iterator.hasNext()){ Map.Entry<String, ImagesModel> groupMap = iterator.next(); String group = groupMap.getKey(); mSourcePhotoMap.remove(group); } } /** * 刪除單個數據 * @param path * @param isDeletePath */ public void delete(String path, boolean isDeletePath) { Iterator<Map.Entry<String,ImagesModel>> groupIterator = mSourcePhotoMap.entrySet().iterator(); mSelectedMap.remove(path); while (groupIterator.hasNext()) { Map.Entry<String, ImagesModel> entry = groupIterator.next(); ImagesModel imagesModel = entry.getValue(); if (imagesModel.getPath().equals(path)) { if(isDeletePath){ boolean res = mImagesDataManager.delete(imagesModel);//刪除媒體庫 if(res) NewImgSearchDbHelper.getInstance().clearCacheForImg(imagesModel.getImgPath()); mSourcePhotoList.remove(imagesModel); mSourcePhotoMap.remove(imagesModel); } } Iterator<NewPhotoBean> PanoramagramIterator = mPanoramagramList.iterator(); while(PanoramagramIterator.hasNext()){ NewPhotoBean newPhotoBean = PanoramagramIterator.next(); if (path.equals(newPhotoBean.model.getPath())){ PanoramagramIterator.remove(); } } Iterator<NewPhotoBean> BeforehandImgIterator = mBeforehandImgList.iterator(); while(BeforehandImgIterator.hasNext()){ NewPhotoBean newPhotoBean = BeforehandImgIterator.next(); if (path.equals(newPhotoBean.model.getPath())){ BeforehandImgIterator.remove(); } } } if (!groupIterator.hasNext()) { groupIterator.remove(); } refreshDataList(); } /** * 全選或取消全選,不包含ui操作 * @param isAllSelect */ public void setSelectAllNoUI(boolean isAllSelect) { if(mSourcePhotoList != null) { mSelectedMap.clear(); if (isAllSelect) { for (ImagesModel model : mData.getImgList()) { mSelectedMap.put(model.getImgPath(), model); } } } } /** * 返回的是實際的數量 * @return */ public int getCount() { if (getColum()==2){ return mDistinguishGroup != null ? mDistinguishGroup.size() : 0; }else if (getColum()==1||getColum()==3){ return mData != null ? mData.getImgList().size() : 0; } return 0; } /** * 獲取源資料,map格式 * @return */ public LinkedHashMap<String,ImagesModel> getDataMap(){ return mSourcePhotoMap; } public boolean isAllSelected() { return mSelectedMap.size() == mDataTotal; } /** * 獲取實際條目數量 * @return */ @Override public int getItemCount() { if (getLayoutManager() instanceof GridLayoutManager) { if (getColum() == 3) { mDataCount=getContentCount() + getHeaderViewCount(); return mDataCount; } else if (getColum() == 2) { mDataCount=getContentCount(); return mDataCount; } else if (getColum() == 1) { //照片牆 mDataCount = getContentCount() > mMaxItemCount ? mMaxItemCount + getHeaderViewCount() + getFooterViewCount() : getContentCount() + getHeaderViewCount() + getFooterViewCount(); return getContentPositionCount(mDataCount - (getHeaderViewCount() + getFooterViewCount())) + getHeaderViewCount() + getFooterViewCount(); } } return 0; } /** * 修改選擇列表,效率極低 * 用於在其它介面修改了選擇項需要重新更新介面卡 * @param selectList */ public void updateSelectList(List<String> selectList) { mSelectedMap.clear(); if(selectList!=null && !selectList.isEmpty()) { int len = selectList.size(); int count =0; if(mSourcePhotoList != null){ for (ImagesModel model : mSourcePhotoList) { for(String sel : selectList){ if(sel.equals(model.getImgPath())){ mSelectedMap.put(sel, model); count++; if (count==len){ notifySelectChange(); return; } } } } } }else { notifySelectChange(); } } /** * 設定是否顯示加密後的圖片 * @param isShow */ public void setShowEncryptImage(boolean isShow, String secretKey){ mIsShowEncryptImage = isShow; mSecretKey = secretKey; } /** * 獲取資料佔用條目數量 * @param contentCount * @return */ private int getContentPositionCount(int contentCount ) { int contentPositionCount=0; int i=0; while(contentCount>i&&contentPositionCount<mItemList.size()){ i+=mLayoutMap.get(mItemList.get(contentPositionCount++)); } return contentPositionCount; } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { mPosition=position; if (holder instanceof HeaderViewHolder) { } else if (holder instanceof FooterViewHolder) { } else if (holder instanceof GridViewHolder) { bindGridViewHolder(holder, position); }else if (holder instanceof ListViewHolder){ bindListViewHolder(holder, position); } } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == ITEM_TYPE_CONTENT_GRID) { return creatContentViewHolder(); } else if (viewType == ITEM_TYPE_HEADER) { return new HeaderViewHolder(mHeaderViews.get(0)); } else if (viewType == ITEM_TYPE_FOOTER) { return new FooterViewHolder(mFooterViews.get(0)); }else if (viewType == ITEM_TYPE_CONTENT_LIST0) { return creatContentViewHolder(); }else if (viewType == ITEM_TYPE_CONTENT_LIST1) { return creatContentViewHolder(); }else if (viewType == ITEM_TYPE_CONTENT_LIST2) { return creatContentViewHolder(); }else if (viewType == ITEM_TYPE_CONTENT_LIST3) { return creatContentViewHolder(); }else if (viewType == ITEM_TYPE_CONTENT_LIST4) { return creatContentViewHolder(); }else if (viewType == ITEM_TYPE_CONTENT_LIST5) { return creatContentViewHolder(); }else if (viewType == ITEM_TYPE_CONTENT_LIST6) { return creatContentViewHolder(); }else if (viewType == ITEM_TYPE_CONTENT_LIST7) { return creatContentViewHolder(); }else if (viewType == ITEM_TYPE_CONTENT_LIST8) { return creatContentViewHolder(); }else if (viewType == ITEM_TYPE_CONTENT_LIST8) { return creatContentViewHolder(); }else if (viewType == ITEM_TYPE_CONTENT_LIST9) { return creatContentViewHolder(); }else if (viewType == ITEM_TYPE_CONTENT_LIST10) { return creatContentViewHolder(); } return null; } /** * 判斷條目型別 */ @Override public int getItemViewType(int position) { if (getLayoutManager() instanceof GridLayoutManager){ if (getHeaderViewCount() != 0 && position < getHeaderViewCount()) { return ITEM_TYPE_HEADER; } else if (getFooterViewCount() != 0 && position >= getItemCount()-getFooterViewCount()){ return ITEM_TYPE_FOOTER; } else { if (getColum()==3||getColum()==2){ return ITEM_TYPE_CONTENT_GRID; }else if (getColum()==1){ if (position==getHeaderViewCount()){ return ITEM_TYPE_CONTENT_LIST0; }else if (position==(getHeaderViewCount()+1)){ return ITEM_TYPE_CONTENT_LIST1; }else if (position==(getHeaderViewCount()+2)){ return ITEM_TYPE_CONTENT_LIST2; }else if (position==(getHeaderViewCount()+3)){ return ITEM_TYPE_CONTENT_LIST3; }else if (position==(getHeaderViewCount()+4)){ return ITEM_TYPE_CONTENT_LIST4; }else if (position==getHeaderViewCount()+5){ return ITEM_TYPE_CONTENT_LIST5; }else if (position==getHeaderViewCount()+6){ return ITEM_TYPE_CONTENT_LIST6; }else if (position==getHeaderViewCount()+7){ return ITEM_TYPE_CONTENT_LIST7; }else if (position==getHeaderViewCount()+8) { return ITEM_TYPE_CONTENT_LIST8; }else if (position==getHeaderViewCount()+9) { return ITEM_TYPE_CONTENT_LIST9; }else if (position==getHeaderViewCount()+10) { return ITEM_TYPE_CONTENT_LIST10; } } } } return -1; } @Override public long getItemId(int position) { return super.getItemId(position); } class HeaderViewHolder extends RecyclerView.ViewHolder { public HeaderViewHolder(View itemView) { super(itemView); } } class FooterViewHolder extends RecyclerView.ViewHolder { public FooterViewHolder(View itemView) { super(itemView); } } private RecyclerView.ViewHolder creatContentViewHolder() { if (getLayoutManager() instanceof GridLayoutManager) { if (getColum() == 3) { View gridView = LayoutInflater.from(mContext).inflate(R.layout.act_moment_detail_content, null); View first=gridView.findViewById(R.id.content); ViewGroup.LayoutParams first_Params = first.getLayoutParams(); first_Params.height=mScreenWidth/3; first.setLayoutParams(first_Params); return new GridViewHolder(gridView); }else if (getColum()==2){ View gridView = LayoutInflater.from(mContext).inflate(R.layout.item_moment_distinguish_sort,null); View first=gridView.findViewById(R.id.item_moment_distinguish_sort_img); ViewGroup.LayoutParams first_Params = first.getLayoutParams(); first_Params.height=mScreenWidth*3/8; first.setLayoutParams(first_Params); return new GridViewHolder(gridView); }else if (getColum() == 1) { int itemView = mItemList.get(mPosition); //實際position=mPosition+getHeaderViewCount itemView為Layout編號 if (itemView == 0 || itemView == 9 || itemView == 10) { View only_one = mInflater.inflate(R.layout.item_only_one_moment, null); return new OnlyOneViewHolder(only_one); } else if (itemView == 1) { View one_big_one_small = mInflater.inflate(R.layout.item_one_big_one_small_moment, null); View one_big_one_small_first = one_big_one_small.findViewById(R.id.first); ViewGroup.LayoutParams one_big_one_small_Params = one_big_one_small_first.getLayoutParams(); one_big_one_small_Params.height = mScreenWidth * 17 / 36; one_big_one_small_first.setLayoutParams(one_big_one_small_Params); return new OneBigOneSmallViewHolder(one_big_one_small); } else if (itemView == 2) { View one_big_three_small = mInflater.inflate(R.layout.item_one_big_three_small_moment, null); View one_big_three_small_first = one_big_three_small.findViewById(R.id.first); ViewGroup.LayoutParams one_big_three_samll_params = one_big_three_small_first.getLayoutParams(); one_big_three_samll_params.height = mScreenWidth * 3 / 4; one_big_three_small_first.setLayoutParams(one_big_three_samll_params); return new OneBigThreeSmallViewHolder(one_big_three_small); } else if (itemView == 3) { View one_big_two_small = mInflater.inflate(R.layout.item_one_big_two_samll_moment, null); View one_big_two_small_first = one_big_two_small.findViewById(R.id.first); ViewGroup.LayoutParams one_big_two_small_Params = one_big_two_small_first.getLayoutParams(); one_big_two_small_Params.height = mScreenWidth * 1 / 2; one_big_two_small_first.setLayoutParams(one_big_two_small_Params); return new OneBigTwoSmallViewHolder(one_big_two_small); } else if (itemView == 4) { View three_big = mInflater.inflate(R.layout.item_three_big_moment, null); View three_big_first = three_big.findViewById(R.id.first); ViewGroup.LayoutParams three_big_params = three_big_first.getLayoutParams(); three_big_params.height = mScreenWidth * 1 / 2; three_big_first.setLayoutParams(three_big_params); return new ThreeBigViewHolder(three_big); } else if (itemView == 5) { View three_small = mInflater.inflate(R.layout.item_three_small_moment, null); View three_small_first = three_small.findViewById(R.id.first); ViewGroup.LayoutParams three_small_params = three_small_first.getLayoutParams(); three_small_params.height = mScreenWidth * 1 / 4; three_small_first.setLayoutParams(three_small_params); return new ThreeSmallViewHolder(three_small); } else if (itemView == 6) { View two_big = mInflater.inflate(R.layout.item_two_big_moment, null); View two_big_first = two_big.findViewById(R.id.first); ViewGroup.LayoutParams two_big_params = two_big_first.getLayoutParams(); two_big_params.height = mScreenWidth * 3 / 4; two_big_first.setLayoutParams(two_big_params); return new TwoBigViewHolder(two_big); } else if (itemView == 7) { View two_small_one_big = mInflater.inflate(R.layout.item_two_samll_one_big_moment, null); View two_small_one_big_third = two_small_one_big.findViewById(R.id.third); ViewGroup.LayoutParams two_small_one_big_params = two_small_one_big_third.getLayoutParams(); two_small_one_big_params.height = mScreenWidth * 1 / 2; two_small_one_big_third.setLayoutParams(two_small_one_big_params); return new TwoSmallOneBigViewHolder(two_small_one_big); } else if (itemView == 8) { View two_small = mInflater.inflate(R.layout.item_two_small_moment, null); View two_small_first = two_small.findViewById(R.id.first); ViewGroup.LayoutParams two_small_params = two_small_first.getLayoutParams(); two_small_params.height = mScreenWidth * 7 / 18; two_small_first.setLayoutParams(two_small_params); return new TwoSmallViewHolder(two_small); } } } return null; } private void bindGridViewHolder(RecyclerView.ViewHolder holder, int position){ if (holder instanceof GridViewHolder) { ((GridViewHolder) holder).refreshView(position); } } private void bindListViewHolder(RecyclerView.ViewHolder holder, int position) { int itemPosition=mItemList.get(position-getHeaderViewCount()); if ((holder instanceof OnlyOneViewHolder)&&(itemPosition==0||itemPosition==9||itemPosition==10)){ ((OnlyOneViewHolder) holder).refreshView(position); }else if ((holder instanceof OneBigOneSmallViewHolder)&&itemPosition==1){ ((OneBigOneSmallViewHolder) holder).refreshView(position); }else if ((holder instanceof OneBigThreeSmallViewHolder)&&itemPosition==2){ ((OneBigThreeSmallViewHolder) holder).refreshView(position); }else if ((holder instanceof OneBigTwoSmallViewHolder)&&itemPosition==3){ ((OneBigTwoSmallViewHolder) holder).refreshView(position); }else if ((holder instanceof ThreeBigViewHolder)&&itemPosition==4){ ((ThreeBigViewHolder) holder).refreshView(position); }else if ((holder instanceof ThreeSmallViewHolder)&&itemPosition==5){ ((ThreeSmallViewHolder) holder).refreshView(position); }else if ((holder instanceof TwoBigViewHolder)&&itemPosition==6){ ((TwoBigViewHolder) holder).refreshView(position); }else if ((holder instanceof TwoSmallOneBigViewHolder)&&itemPosition==7){ ((TwoSmallOneBigViewHolder) holder).refreshView(position); }else if ((holder instanceof TwoSmallViewHolder)&&itemPosition==8){ ((TwoSmallViewHolder) holder).refreshView(position); } } class GridViewHolder extends RecyclerView.ViewHolder { public View view; public GridViewHolder(View itemView) { super(itemView); view=itemView; } public void refreshView(int position){ if (getColum()==3) { View itemView=view.findViewById(R.id.content); refreshPerView(position-getHeaderViewCount(), itemView,position); }else if (getColum()==2){ RoundImageView img = (RoundImageView) view.findViewById(R.id.item_moment_distinguish_sort_img); TextView name = (TextView) view.findViewById(R.id.item_moment_distinguish_name); name.setText(mDistinguishGroup.get(position).getSubTagName()); TextView num = (TextView) view.findViewById(R.id.item_moment_distinguish_num); num.setText(mContext.getResources().getString(R.string.act_moment_detail_footer_distinguish_num,mDistinguishGroup.get(position).items.size())); loadImg(img,null,mDistinguishGroup.get(position).getSubTagCoverThumbPath()); setClickEvent(view, position); } } } private abstract class ListViewHolder extends RecyclerView.ViewHolder { public View view; public ListViewHolder(View itemView) { super(itemView); view=itemView; } public abstract void refreshView(int position); } private class OnlyOneViewHolder extends ListViewHolder { public OnlyOneViewHolder(View itemView) { super(itemView); } @Override public void refreshView(int position) { int[] height ={18,14,22}; int i = 0; int itemPosition=mItemList.get(position-getHeaderViewCount()); //控制條目不可複用,限制條目的高度,此處獲取的是佈局編號 if (itemPosition==0){ i=0; }else if (itemPosition==9){ i=1; }else if (itemPosition==10){ i=2; } View only_one_first=view.findViewById(R.id.first); if (only_one_first.getTag()==null) { ViewGroup.LayoutParams only_one_Params = only_one_first.getLayoutParams(); only_one_Params.height = mScreenWidth * (height[i]) / 36; only_one_first.setLayoutParams(only_one_Params); only_one_first.setTag(itemPosition); } refreshListPerView(view, position, R.id.first, 0); } } private class OneBigOneSmallViewHolder extends ListViewHolder { public OneBigOneSmallViewHolder(View view) { super(view); } @Override public void refreshView(int position) { refreshListPerView(view, position, R.id.first, 0); refreshListPerView(view, position, R.id.second, 1); } } private class OneBigThreeSmallViewHolder extends ListViewHolder { public OneBigThreeSmallViewHolder(View view) { super(view); } @Override public void refreshView(int position) { refreshListPerView(view, position, R.id.first, 0); refreshListPerView(view, position, R.id.second, 1); refreshListPerView(view, position, R.id.third, 2); refreshListPerView(view, position, R.id.fourth, 3); } } private class OneBigTwoSmallViewHolder extends ListViewHolder { public OneBigTwoSmallViewHolder(View view) { super(view); } @Override public void refreshView(int position) { refreshListPerView(view, position, R.id.first, 0); refreshListPerView(view, position, R.id.second, 1); refreshListPerView(view, position, R.id.third, 2); } } private class ThreeBigViewHolder extends ListViewHolder { View chlidView; public ThreeBigViewHolder(View view) { super(view); } @Override public void refreshView(int position) { refreshListPerView(view, position, R.id.first, 0); refreshListPerView(view, position, R.id.second, 1); refreshListPerView(view, position, R.id.third, 2); } } private class ThreeSmallViewHolder extends ListViewHolder { public ThreeSmallViewHolder(View view) {super(view);} @Override public void refreshView(int position) { refreshListPerView(view, position, R.id.first, 0); refreshListPerView(view, position, R.id.second, 1); refreshListPerView(view, position, R.id.third, 2); } } private class TwoBigViewHolder extends ListViewHolder { public TwoBigViewHolder(View view) {super(view);} @Override public void refreshView(int position) { refreshListPerView(view, position, R.id.first, 0); refreshListPerView(view, position, R.id.second, 1); } } private class TwoSmallOneBigViewHolder extends ListViewHolder { public TwoSmallOneBigViewHolder(View view) {super(view);} @Override public void refreshView(int position) { refreshListPerView(view, position, R.id.first, 0); refreshListPerView(view, position, R.id.second, 1); refreshListPerView(view, position, R.id.third, 2); } } private class TwoSmallViewHolder extends ListViewHolder { public TwoSmallViewHolder(View view) {super(view);} @Override public void refreshView(int position) { refreshListPerView(view, position, R.id.first, 0); refreshListPerView(view, position, R.id.second, 1); } } /** * 獲取position-1內格子總量 * @param position * @return */ private int getFrontDataCount(int position) { int frontPosition=0; //position-1內每個layout的index int frontDataCount=0; //position-1內所有子View總量 while (frontPosition<position-1){ frontDataCount+=mLayoutMap.get(mItemList.get(frontPosition++)); } return frontDataCount; } /** * spanCount==1時每個格子填充圖片資料 * @param view * @param position * @param id * @param index */ private void refreshListPerView(View view,int position,int id,int index) { int frontDataCount = getFrontDataCount(position); int curIndex = frontDataCount + index; View perView = view.findViewById(id); //單個格子 if (curIndex < mDataCount - getHeaderViewCount() - getFooterViewCount()) { refreshPerView(curIndex, perView,position); } else { perView.setVisibility(View.GONE); } } private ArrayList<ImagesModel> mNewPhotoList = new ArrayList<>(); //資料重排之後的集合 private ArrayList<NewPhotoBean> mNewPhotoBeanList = new ArrayList<>(); //資料重排之後的集合 /** * getColum()==1或 getColum()==3每個格子填充圖片資料 * @param curIndex * @param perView */ private void refreshPerView(final int curIndex, View perView,int position) { final CoverImageView picView = (CoverImageView) perView.findViewById(R.id.iv); final CheckBox picCheckBox = (CheckBox) perView.findViewById(R.id.check); ImageView ivUploadTag = (ImageView) perView.findViewById(R.id.iv_upload_tag); ImagesModel model = null; if (getLayoutManager() instanceof GridLayoutManager){ Log.d("dddd",position+" aaa"); if (getColum()==1){ //顯示預載入圖片 if (curIndex>=mNewPhotoBeanList.size()) { // picView.setImageDrawable(null); // picView.setTag(R.id.iv, null); // picView.setCoverShow(false); perView.setVisibility(View.GONE); return; } NewPhotoBean newPhotoBean = mNewPhotoBeanList.get(curIndex); Bitmap bitmap = newPhotoBean.bitmap; model=newPhotoBean.model; if (model==null||bitmap==null){ perView.setVisibility(View.GONE); return; } int itemPosition=mItemList.get(position-getHeaderViewCount()); //獲取當前佈局編號 if (itemPosition==0||itemPosition==9||itemPosition==10){ //存在全景圖時,大圖佈局優先載入全景圖 if ((bitmap.getWidth()/bitmap.getHeight())>=4){ View only_one_first = perView.findViewById(R.id.first); ViewGroup.LayoutParams only_one_Params = only_one_first.getLayoutParams(); only_one_Params.height = mScreenWidth * 7 / 36; only_one_first.setLayoutParams(only_one_Params); } isShowPicView(perView, picView,bitmap); }else{ isShowPicView(perView, picView,bitmap); } }else{ //載入圖片 model = mSourcePhotoList.get(curIndex); loadImg(picView,model, model.thumbnailPath); } } ivUploadTag.setVisibility(View.VISIBLE); //檢測是當前照片是否已上傳到雲端 if(model.isUploaded()) { ivUploadTag.setBackgroundResource(R.drawable.img_uploaded); }else { ivUploadTag.setBackgroundResource(R.drawable.img_not_upload); } if (mIsEdit) { boolean checked = mSelectedMap.containsKey(model.getPath()); picCheckBox.setOnCheckedChangeListener(null);// 清除之前的監聽 picCheckBox.setChecked(checked); picView.setCoverShow(checked); if (picCheckBox.getVisibility() != View.VISIBLE) { picCheckBox.setVisibility(View.VISIBLE); } // 選擇 picCheckBox.setTag(model); picCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { Object tag = buttonView.getTag(); if (tag == null || !(tag instanceof ImagesModel)) { //非法資料 return; } // 修改選擇列表 ImagesModel innerModel = (ImagesModel) tag; String path = innerModel.getPath(); if (isChecked) { if (!mSelectedMap.containsKey(path)) { mSelectedMap.put(path, innerModel); // changeGroupSelect(true, path); picView.setCoverShow(true); } } else { mSelectedMap.remove(path); //changeGroupSelect(false,path); picView.setCoverShow(false); } //notifyUI2SelectChanged(); sendUiSelectChanged(true, innerModel, isChecked); } }); if (mClickShowBigImage) { picView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(onItemClickListener != null) { onItemClickListener.onItemClick(curIndex); } } }); } else { picView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { picCheckBox.performClick();// 單擊選擇 } }); } }else { picView.setCoverShow(false); if (picCheckBox.getVisibility() != View.GONE) { picCheckBox.setVisibility(View.GONE); } picView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(onItemClickListener != null) { onItemClickListener.onItemClick(curIndex); } } }); } } /** * 展示圖片 * @param perView * @param picView */ private void isShowPicView(View perView, CoverImageView picView, Bitmap bitmap) { if (bitmap==null){ picView.setImageDrawable(null); picView.setTag(R.id.iv, null); picView.setCoverShow(false); perView.setVisibility(View.GONE); }else{ picView.setImageBitmap(bitmap); } } /** * 載入圖片 * @param picView * @param model * @param path */ private void loadImg(ImageView picView, ImagesModel model, String path) { String pathUtlDes = null; boolean hasHeader = false; if (!CXUtil.isEmpty(path)) { if (path.startsWith("http://")) { pathUtlDes = path; } else { pathUtlDes = (path.startsWith("file://"))?path: "file://" + path; } } else { if (model!=null) { pathUtlDes = (model.getPath().startsWith("file://"))? model.getPath(): "file://" + model.getPath(); } hasHeader = mIsShowEncryptImage? true: false; } String pathUrlOrg = (String) picView.getTag(R.id.iv); if (null == pathUrlOrg || !pathUrlOrg.endsWith(pathUtlDes)) { picView.setImageDrawable(null); //是否需要顯示預設的長方形圖片,防止單張圖片拉伸變形問題 ViewGroup.LayoutParams layoutParams = picView.getLayoutParams(); boolean isRectangle = Math.abs((layoutParams.width - layoutParams.height)) > mSideMargin; if (mIsShowEncryptImage) {//顯示網路加密圖片 //洩漏 去掉無用的監聽,避免洩漏 boolean isSkipThumbanialHead=false; CXImageLoaderUtil.getInstance(mContext).displayImage(picView, pathUtlDes, mIsDataFromNet ? DisplayImageOptionsFactory.getCloudImageOptions(mSecretKey, isSkipThumbanialHead, isRectangle) : DisplayImageOptionsFactory.getLocalSecretImageOptions(mSecretKey,hasHeader,isRectangle)); } else {//顯示本地圖片 mImageLoaderUtil.displayImage(picView,pathUtlDes,isRectangle? mPectanglePhotoOption: mPhotoOption); } picView.setTag(R.id.iv, pathUtlDes); } else { // 圖片相同不載入 } } /** * 當 getColum()==4時每個格子點選事件回撥處理 * @param view * @param childPosition */ private void setClickEvent(View view, final int childPosition) { view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(onItemClickListener != null) { onItemClickListener.onItemClick(childPosition); } } }); } public boolean isEdit() { return mIsEdit; } }
相關推薦
RecyclerView高仿IOS照片瀑布流式展示圖片效果
摘要: 蘋果有自己的元件能夠很快捷方便的實現這種類似瀑布流但是比瀑布流更為複雜的照片展示效果,當時接到這個需求時我也是一臉懵逼,而且查閱很多資料以及請教一些同行都沒有找到更好的idea,以此在與同事共同商討之下最終確立設計方式,此佈局能夠自動根據圖片大小進行智慧尋找更合適的
Android 高仿微信發朋友圈瀏覽圖片效果
最近一直在高仿微信、高仿微信,今天小編再給大家分享一個仿微信發朋友圈瀏覽圖片的效果.... 好了,先看一下效果吧: 下面就來說一下具體怎麼實現的: 實現思路 1.首先我們要獲取資料來源,資料來源就是我們的每條說說(包括姓名、標題、圖片陣列)
Android學習之RecyclerView學習(實現瀑布流式佈局)
RecyclerView,大家可以通過匯入support-v7對其進行使用。 如果使用AndroidStudio開發, 需要在build.gradle中新增: compile 'com.android.support:appcompat-v7:24.2.1' com
高仿IOS---Dialog(底部式)
activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.andro
Android 實現高仿iOS桌面效果之可拖動的GridView(上)
最近專案中遇到一個LIstview的拖動效果,github上一搜發現有叫DragListview的開源專案,然後自己再小手一搜拖動排序的GridView,卻沒發現什麼很全很好的開源專案,後
高仿ios SwitchButton----(自認為仿的還不錯)
這篇文章來介紹這兩天的成果,android自帶的switchbutton太難看了,於是照著ios的switchbutton做了一個高仿的自定義switchbutton,目前還不是很完美,程式碼也還比較亂,但還是分享出來,望大家指教! 先看效果圖(不知道怎麼搞gif圖片,就先
Android控制元件RecyclerView實現橫向滑動、瀑布流。
在開發的過程中,我們經常使用ListView控制元件,但是ListView也有它的缺點,就是它不能夠左右滑動資料,執行效率不高; 所以我們可以使用更強大的控制元件RecyclerView,可以說它是一個增強版的ListView,Google推薦使用,那就簡單的
UICollectionView(純程式碼方式)實現帶上下拉重新整理的瀑布流式
瀑布流(WaterFlow)是專案開發過程中的常見佈局,有關於瀑布流(WaterFlow)的實現方式:在UICollectionView未出現之前,瀑布流的實現多半是採用UIScrollView或是UITableView。對於我們這種用慣了表檢視的人來說,UIC
安卓開發-高仿ios時間選擇控制元件timepicker
在開發中如果有地址或者日期選擇等就會涉及到時間或者條件選擇器,大家都會想到仿ios的三級聯動的效果,用wheelview實現,其實安卓原生自帶了時間和日期選擇器可能是效果來說太粗獷了,所以很多產品效果圖都是清一色的ios那種效果,ok,廢話說完了上圖 demo地址:htt
高仿 IOS遨遊哈哈最新版
因為自己從大學開始一直是用遨遊瀏覽器,一不小心點了最下方的狀態列,從此走上了不歸路,傲遊瀏覽器也算是陪伴了我三四年的時間,遨遊哈哈功能是我經常去的版塊之一(申明:不是打廣告)。
“瀑布流式”圖片懶載入程式碼示例
最近專案使用到了“懶載入”,現在更新一般,因為平時主要使移動端的開發所以庫檔案使用的是zepto.js 。當然也可以和jQuery 通用。 程式碼如下: /** * Created by zhiqiang on 2015/10/14. * [email&
瀑布流式標籤
實現背景 打造Android中的流式佈局和熱門標籤 看到鴻洋大神的這個視訊教程有感而發,於是自己重新寫了一遍這個viewgroup,大體思路一致,不過關鍵地方改成了我自己比較容易理解的演算法: 對於標籤直接的間距,鴻洋大神用的是給標籤設
IOS UICollectionView瀑布流 CHTCollectionViewWaterfallLayout用法
實現瀑布流的類要繼承的代理<UICollectionViewDelegate, UICollectionViewDataSource,CHTCollectionViewDelegateWaterfallLayout> CHTCollectionViewWate
高仿iOS的BlurDialog
文/BlackSwift(簡書作者) 原文連結:http://www.jianshu.com/p/1e2d68183c3c 著作權歸作者所有,轉載請聯絡作者獲得授權,並標註“簡書作者”。本文主要討論Dialog的blur背景與泛談window中的各種view。 Github上有許多仿iOS的dialog,但是
android 高仿IOS水滴版上下拉重新整理的Listview
之前有分享一些重新整理的Demo,最近找到一個重新整理的例子,分享給大家。同時感謝原作者的分享! 現在給大家分享一個高仿IOS的Listview重新整理效果,支援上下拉重新
純JS、CSS3實現高仿IOS訊息alert彈窗(警告框,確認框,提示框)。老鐵們,沒毛病。
簡潔,大方的ios彈窗風格。網上有很多關於alert 彈窗的栗子可以借鑑使用。本文章主要應用在移動端上面的彈窗實現。 在專案沒有應用到其他框架彈窗的基礎上, 此例項應該可以滿足大部分彈窗上的要求,可直接應用於專案之中。使用方法: 1、引入依賴的樣式檔案和指
android高仿今日頭條小視訊轉場切換效果
可以先看看今日頭條效果 功能分析 點選列表上的一個item,該item會放大,最後直接全屏播放小視訊,剛開始看上去,以為是個共享元素的轉場動畫, 後來想到,共享元素要在android 5.0以上支援,而今日頭條顯然不會只支援5.0版本以上 筆者想到的一種方案就是進入Acti
PickerView--仿ios滾輪時間選擇、城市選擇效果
在專案開發中Android基本都是在跟隨ios的風格,前段時間產品經理就要求按照ios的效果,做時間、城市選擇效果,真要全部自己寫還真有點蛋疼,所以在網上一搜,效果不少,其中PickerView用的人還是蠻多的,所以就決定用PickerView來實現; PickerView提供了:時間選擇器
Android高仿京東淘寶商品列表佈局切換效果
商品列表佈局切換效果很常見,因為淘寶京東有的介面下面很多公司都會給風模仿 當然,我們公司也不例外,最近版本更新添加了這個功能; 在專案中直接使用RecyclerView實現切換功能; 如果不瞭解RecyclerView的可以先看下: RecyclerView使用詳解
計算從ios照片庫中選取的圖片檔案大小
從 iphone 的 照片庫中選取的圖片,由於 系統不能返回其檔案的具體路徑,所以這時要用到 ALAssetsLibrary 程式碼如下: ALAssetsLibrary* alLibrary = [[ALAssetsLibrary alloc] init]