在Listview中旋转图像

时间:2013-03-23 23:08:57

标签: android scala imageview android-arrayadapter

我正在尝试制作一个假的水平ListView。为此,我想旋转适配器中每个单元格的内容。它几乎可以工作:

Turn graphics

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
    }
}

唯一的问题是它不显示第一张图片。相反,它显示如下: Listview empty

要显示第一个列表,我需要单击每个列表中的一个元素。 onclick方法如下:

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)
    }
  })

然后我尝试将mAdapter.notifyDataSetChanged()放在片段的onResume函数中,但它不会从头开始更新列表。我仍然需要点击某些内容才能显示所有图片。 知道为什么吗?

1 个答案:

答案 0 :(得分:0)

我发现iv.getWidth()和iv.getHeight()都返回零,因为getview将由onActivityCreated函数调用。将notifyDataSetChanged()放在onResume函数中太早了。因此,drawable将以0大小绘制,并在我点击按钮时重新加载。

所以要改变这一点,我编写了下面的代码片段,用一个监听器调用resize函数。

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)
  }
})