Vertical (rotated) label in Android

后端 未结 10 1111
礼貌的吻别
礼貌的吻别 2020-11-22 08:04

I need 2 ways of showing vertical label in Android:

  1. Horizontal label turned 90 degrees counterclockwise (letters on the side)
  2. Horizontal label with l
10条回答
  •  执笔经年
    2020-11-22 08:26

    My initial approach to rendering vertical text inside a vertical LinearLayout was as follows (this is Kotlin, in Java use setRoatation etc.):

    val tv = TextView(context)
    tv.gravity = Gravity.CENTER
    tv.rotation = 90F
    tv.height = calcHeight(...)
    linearLabels.addView(tv)
    

    As you can see the problem is that the TextView goes vertically but still treats its width as if it were oriented horizontally! =/

    Thus approach #2 consisted of additionally switching width and height manually to account for this:

    tv.measure(0, 0)
    // tv.setSingleLine()
    tv.width = tv.measuredHeight
    tv.height = calcHeight(...)
    

    This however resulted in the labels wrapping around to the next line (or being cropped if you setSingleLine) after the relatively short width. Again, this boils down to confusing x with y.

    My approach #3 was thus to wrap the TextView in a RelativeLayout. The idea is to allow the TextView any width it wants by extending it far to the left and the right (here, 200 pixels in both directions). But then I give the RelativeLayout negative margins to ensure it is drawn as a narrow column. Here is my full code for this screenshot:

    val tv = TextView(context)
    tv.text = getLabel(...)
    tv.gravity = Gravity.CENTER
    tv.rotation = 90F
    
    tv.measure(0, 0)
    tv.width = tv.measuredHeight + 400  // 400 IQ
    tv.height = calcHeight(...)
    
    val tvHolder = RelativeLayout(context)
    val lp = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
        LinearLayout.LayoutParams.WRAP_CONTENT)
    lp.setMargins(-200, 0, -200, 0)
    tvHolder.layoutParams = lp
    tvHolder.addView(tv)
    linearLabels.addView(tvHolder)
    
    val iv = ImageView(context)
    iv.setImageResource(R.drawable.divider)
    linearLabels.addView(iv)
    

    As a general tip, this strategy of having a view "hold" another view has been really useful for me in positioning things in Android! For example, the info window below the ActionBar uses the same tactic!

    For text appearing like a store sign just insert newlines after each character, e.g. "N\nu\nt\ns" will be:

提交回复
热议问题