Rotating images in Listview

杀马特。学长 韩版系。学妹 提交于 2019-12-11 04:22:53

问题


I am trying to make a fake horizontal ListView. For that, I want to rotate the content of each cell in the adapter. It almost works:

class ImageAdapter(ctx: Context, viewResourceId: Int, imageResourceId: Int, strings: Array[String], icons: TypedArray, colorSelected: Int, colorNotSelected: Int, colorBorder: Int) extends ArrayAdapter[String](ctx, viewResourceId, strings) {
    // Useful variables
    private val mInflater: LayoutInflater = ctx.getSystemService(
                Context.LAYOUT_INFLATER_SERVICE).asInstanceOf[LayoutInflater]
    private val mStrings: Array[String] = strings
    private val mIcons: TypedArray = icons
    private val mViewResourceId: Int = viewResourceId

    private var mSelected : Int = 0

    def setSelected(s: Int) = mSelected = s

    // Inherited from ArrayAdapter
    override def getCount():Int = mStrings.length
    override def getItem(position: Int): String = mStrings(position)
    override def getItemId(position: Int): Long = position

    // The rotation machinery
    var rotation = 90
    private var matrix = new Matrix()
    val rect1 = new RectF(0, 0, 0, 0)
    val rect2 = new RectF(0, 0, 0, 0)
    val cst = Matrix.ScaleToFit.CENTER

    // Getting the view.
    override def getView(position: Int, convertView: View, parent: ViewGroup): View = {
        var result = if(convertView == null) mInflater.inflate(mViewResourceId, null) else convertView

        var iv: ImageView = result.findViewById(imageResourceId).asInstanceOf[ImageView]
        val drawable = mIcons.getDrawable(position)
        iv.setScaleType(ScaleType.MATRIX)
        matrix.reset()
        val height = drawable.getIntrinsicHeight()
        val width = drawable.getIntrinsicWidth()
        rotation match {
          case 0 =>
            rect1.set(0, 0, width, height)
            rect2.set(0, 0, iv.getWidth(), iv.getHeight())
            matrix.setRectToRect(rect1, rect2, cst)
          case 90 =>
            rect1.set(0, 0, width, height)
            rect2.set(-iv.getHeight()/2, -iv.getWidth()/2, iv.getHeight()/2, iv.getWidth()/2)
            matrix.setRectToRect(rect1, rect2, cst)
            matrix.postRotate(rotation, 0, 0)
            matrix.postTranslate(iv.getWidth()/2, iv.getHeight()/2)
          ...
          case _ =>
        }
        iv.setImageMatrix(matrix)
        iv.setImageDrawable(drawable)
        iv.postInvalidate()

        if(position == mSelected) {
          result.setBackgroundColor(colorSelected)
        } else {
          result.setBackgroundColor(colorNotSelected)
        }
        result.setTag(mStrings(position))
        result
    }
}

The only problem is that it does not display the first picture. Instead, it displays this:

For the first list to appear, I need to click on one element of each list. The onclick method is the following:

listGraphismesView.setOnItemClickListener(new OnItemClickListener {
    override def onItemClick(parent: AdapterView[_], view: View, position: Int, notUsedId: Long) = {
      var graphismeName = view.getTag().asInstanceOf[String]
      mAdapter.setSelected(position)
      mAdapter.notifyDataSetChanged()
      showGChallenge(position, graphismeName)
    }
  })

I tried then to put mAdapter.notifyDataSetChanged() in the onResume function of the fragment, but it does not update the list from the beginning. I still need to click on something for all images to appear. Any idea why ?


回答1:


I found out that iv.getWidth() and iv.getHeight() were both returning zero because the getview would be called by the onActivityCreated function. Putting notifyDataSetChanged() in the onResume function was too early too. So the drawable would be drawn with size 0, and reloaded when I could click on the button.

So to change that, I wrote the following piece of code, calling the resize function with a listener.

var iv: ImageView = result.findViewById(imageResourceId).asInstanceOf[ImageView]
val drawable = mIcons.getDrawable(position)
iv.setImageDrawable(drawable)
iv.setScaleType(ScaleType.MATRIX)
val vto = iv.getViewTreeObserver()
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
  private var matrix = new Matrix()
  val rect1 = new RectF(0, 0, 0, 0)
  val rect2 = new RectF(0, 0, 0, 0)
  private var height = drawable.getIntrinsicHeight()
  private var width = drawable.getIntrinsicWidth()
  override def onGlobalLayout() {
    val iv_width = iv.getWidth
    val iv_height = iv.getHeight
    matrix.reset()
    rotation match {
      case 0 =>
        rect1.set(0, 0, width, height)
        rect2.set(0, 0, iv_width, iv_height)
        matrix.setRectToRect(rect1, rect2, cst)
      case 90 =>
        rect1.set(0, 0, width, height)
        rect2.set(-iv_height/2, -iv_width/2, iv_height/2, iv_width/2)
        matrix.setRectToRect(rect1, rect2, cst)
        matrix.postRotate(rotation, 0, 0)
        matrix.postTranslate(iv_width/2, iv_height/2)
      ...
      case _ =>
    }
    iv.setImageMatrix(matrix)
  }
})


来源:https://stackoverflow.com/questions/15593152/rotating-images-in-listview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!