<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Android圖片上傳九宮格(添加,刪除,預覽)

          共 8824字,需瀏覽 18分鐘

           ·

          2022-04-24 09:19

          越來越多的功能需要圖片上傳,所以封裝了一個圖片選取,展示的九宮格控件.包含了添加,刪除,以及預覽(為方便自定義,預覽只提供點擊方式外部自定義預覽實現(xiàn))的功能,如圖所示:



          思路:


          1. 自定義ViewGroup 包含RecycleView 實現(xiàn)九宮格

          2. 自定義屬性 設置展示的行數(shù),最大添加的個數(shù)設置AddItem 圖片的展示樣式,以及設置關閉按鈕和錯誤頁展示的央視

          3. 利用RecycleView 的 GridLayoutManager 設置九宮格展示

          4. 根據(jù)邏輯需要在RecyclerView.Adapter中動態(tài)添加圖片和Add頁面的兩種不同他的Item

          5. 根據(jù)添加數(shù)據(jù)有沒有AddItem類型動態(tài)處理數(shù)據(jù)


          實現(xiàn):


          1.attrs.xml自定義屬性

              



          2.九宮格RecycleView的Adapter

          class AddImagesAdapter(    mContext: Context,    limtNum: Int,    addImgs: Int,    addCloseImgs: Int,    addErrImgs: Int,    addLimitNums: Int) :    RecyclerView.Adapter() {    var mContext: Context    var limtNum = 5    var addImgs = -1    var addCloseImgs = -1    var addErrImgs = -1    var addLimitNums = 9    var addImages = ArrayList()
          init { this.mContext = mContext this.limtNum = limtNum this.addCloseImgs = addCloseImgs this.addImgs = addImgs this.addErrImgs = addErrImgs this.addLimitNums = addLimitNums }
          var listener: OnAddClickListener? = null
          fun setOnAddListener(listener: OnAddClickListener) { this.listener = listener }
          fun getHeight(): Int { return (getScreenWidth(mContext)) / 5 }
          private fun dip2px(context: Context, dp: Int): Int { val density = context.resources.displayMetrics.density return (dp * density + 0.5).toInt() }
          private fun getScreenWidth(context: Context): Int { val wm = context .getSystemService(Context.WINDOW_SERVICE) as WindowManager val outMetrics = DisplayMetrics() wm.defaultDisplay.getMetrics(outMetrics) return outMetrics.widthPixels }

          override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { var viedataBinding: ItemAddImagesBinding = DataBindingUtil.inflate( LayoutInflater.from(mContext), R.layout.item_add_images, parent, false )
          var layout = RelativeLayout.LayoutParams(getHeight(), getHeight()) layout.setMargins(dip2px(mContext,1), dip2px(mContext,1), dip2px(mContext,1), dip2px(mContext,1)) viedataBinding.root.layoutParams = layout
          var dataBindingViewHolder: AddImagesViewHolder = AddImagesViewHolder(viedataBinding.root) dataBindingViewHolder.setBinding(viewBinding = viedataBinding) return dataBindingViewHolder }

          override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { var ktHolder = holder as? AddImagesViewHolder var binding = ktHolder!!.getBinding() as ItemAddImagesBinding ktHolder?.getBinding()?.executePendingBindings() if (addImgs!=-1){ binding!!.ivAdd.setBackgroundResource(addImgs) }else{ binding!!.ivAdd.setBackgroundResource(R.drawable.iv_add_images_add) } if (addCloseImgs!=-1){ binding!!.ivClose.setBackgroundResource(addCloseImgs) }else{ binding!!.ivClose.setBackgroundResource(R.drawable.iv_add_img_close) }

          binding.rlClose.setOnClickListener { processDelete(getItem(position)) }
          binding.rlAdd.setOnClickListener { if (listener != null) listener!!.onAddClick(binding.rlAdd, getItem(position)) }
          binding.ivContent.setOnClickListener { if (listener != null) listener!!.onAddClick(binding.ivContent, getItem(position)) }
          if (getItem(position)!!.type.equals("2")) { binding.ivContent.visibility = View.VISIBLE binding.rlClose.visibility = View.VISIBLE binding.rlAdd.visibility = View.GONE if (addErrImgs!=-1){ var requestOptions= RequestOptions().error(addErrImgs) Glide.with(mContext).load(getItem(position)!!.imgUrl).apply(requestOptions).into(binding.ivContent) }else{ var requestOptions= RequestOptions().error(R.drawable.iv_add_err) Glide.with(mContext).load(getItem(position)!!.imgUrl).apply(requestOptions).into(binding.ivContent) }
          } else { binding.ivContent.visibility = View.GONE binding.rlAdd.visibility = View.VISIBLE binding.rlClose.visibility = View.GONE }
          }
          private fun processDelete(item: AddImagesInfo?) { addImages.remove(item) if (!hasAdd()) { addItem(AddImagesInfo(R.drawable.iv_add_images_add, "1")) } else { notifyDataSetChanged()????????} }
          fun addItems(lists: List) { processData(lists) }
          fun addItem(info: AddImagesInfo) { addImages.add(info) notifyDataSetChanged() }
          fun getItems(): ArrayList? { if (this.addImages == null) this.addImages = ArrayList() return this.addImages }
          private fun processData(addDatas: List) { if (addDatas == null) return
          var newList = processEnd(getItems()!!) if (newList.size >= limtNum) return if (newList!!.size + addDatas.size < addLimitNums) { newList!!.addAll(addDatas) newList!!.add(AddImagesInfo("", "1")) } else { newList!!.addAll(addDatas.subList(0, addLimitNums - newList.size)) }????????notifyDataSetChanged() }
          private fun processEnd(addDatas: ArrayList): ArrayList { if (addDatas == null) return addDatas var iterator = addDatas.iterator() while (iterator.hasNext()) { var info = iterator.next() if (info.type.equals("1")) iterator.remove() } return addDatas }
          private fun hasAdd(): Boolean { getItems()!!.forEach { if (it.type.equals("1")) { return true } } return false????}
          override fun getItemCount(): Int { return addImages.size }
          fun getItem(position: Int): AddImagesInfo? { if (addImages != null && position < addImages!!.size) { return this.addImages!!.get(position) } return null }
          interface OnAddClickListener { fun onAddClick(view: View?, item: AddImagesInfo?) }}


          3.自定義ViewGroup

          class AddImagesView @JvmOverloads constructor(    mContext: Context,    attrs: AttributeSet? = null,    defStyleAttr: Int = 0) : FrameLayout(mContext, attrs, defStyleAttr) {    private var mContext: Context    // 添加的圖片資源    private var addImgs = -1    //關閉的圖片資源    private var addCloseImgs = -1    //錯誤頁的圖片資源    private var addErrImgs = -1    //列數(shù)    private var columnNums = 5    //最大圖片數(shù)    private var add_limit_nums = 9
          private var mAdapter: AddImagesAdapter? = null

          init { this.mContext = mContext val tapeArray = mContext.obtainStyledAttributes(attrs, R.styleable.AddImagesStyle) addImgs = tapeArray.getResourceId(R.styleable.AddImagesStyle_add_imgs, -1) addCloseImgs = tapeArray.getResourceId(R.styleable.AddImagesStyle_add_close_imgs, -1) addErrImgs = tapeArray.getResourceId(R.styleable.AddImagesStyle_add_err_imgs, -1) columnNums = tapeArray.getInt(R.styleable.AddImagesStyle_column_nums, 5) add_limit_nums = tapeArray.getInt(R.styleable.AddImagesStyle_add_limit_nums, 9) initView() }
          var listener: AddImagesViewListener? = null
          fun setAddImagesViewListener(listener: AddImagesViewListener) { this.listener = listener }
          //初始換數(shù)據(jù) private fun initView() { var binding = DataBindingUtil.inflate( LayoutInflater.from(mContext), R.layout.layout_add_images, this, false ) addView(binding.root) if (columnNums>5)columnNums=5 binding.rvContent.layoutManager = GridLayoutManager(mContext, columnNums) mAdapter = AddImagesAdapter(mContext, columnNums,addImgs,addCloseImgs,addErrImgs,add_limit_nums) binding.rvContent.adapter = mAdapter mAdapter!!.addItem(AddImagesInfo("", "1")) mAdapter!!.setOnAddListener(object : AddImagesAdapter.OnAddClickListener { override fun onAddClick(view: View?, item: AddImagesInfo?) { when (view!!.id) { R.id.rl_add -> { if (listener!=null) listener!!.onAdd() } R.id.iv_content -> { if (listener!=null) listener!!.onPreview(item,mAdapter!!.getItems()) } } }
          }) } //添加數(shù)據(jù) fun addAddImages(lists: List<AddImagesInfo>) { mAdapter!!.addItems(lists) }

          interface AddImagesViewListener { fun onAdd() fun onPreview(item:AddImagesInfo?,lists: List<AddImagesInfo>?) }
          }


          總結(jié):


          自定義ViewGroup 中間的布局可以設置成動態(tài)添加RecycleView,圖片預覽功能可以根據(jù)項目需要封裝在庫中,在此沒做單獨設置(需要封裝通用傳遞的數(shù)據(jù)),用到的小伙伴可以根據(jù)自己需要再單獨擴展。


          源碼地址:

          https://github.com/wukuiqing49/AddImageViews


          到這里就結(jié)束啦。

          瀏覽 64
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产视频久久免费 | 大香蕉精品在线视频 | 日本黄色电影网站视频 | 98无码人妻精品一区二区三区 | 青娱乐澳门久久 |