调整布局以占据屏幕的百分比

时间:2020-10-02 07:22:54

标签: android xml android-layout kotlin

如何使自定义视图仅占据屏幕的33%,并使其在每个设备上按比例显示?

这应该在下面的xml文件中或在自定义视图kotlin类中处理,因为它是库的一部分,并且我无权访问将托管我的自定义类的视图。

buff_view.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:id="@+id/mainLinearLayout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <include layout="@layout/buff_sender"/>
    <include layout="@layout/buff_question"/>

    <LinearLayout
        android:id="@+id/answersContainer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"/>

</LinearLayout>

buff_sender.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="4dp"
    android:orientation="horizontal">

    <LinearLayout

        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/light_bg"
        android:orientation="horizontal"
        tools:ignore="RtlHardcoded">

        <ImageView
            android:id="@+id/sender_image"
            android:layout_width="27dp"
            android:layout_height="27dp"
            android:layout_gravity="center_vertical"
            android:padding="4dp" />

        <TextView
            android:id="@+id/sender_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:padding="4dp"
            tools:text="Praveen"
            android:textColor="@color/test_color_dark"
            android:textStyle="bold" />
    </LinearLayout>

    <androidx.appcompat.widget.AppCompatImageButton
        android:id="@+id/buff_close"
        android:layout_width="26dp"
        android:layout_height="26dp"
        android:layout_alignParentEnd="true"
        android:background="@drawable/ic_btn_close" />

</RelativeLayout>

buff_question.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/dark_bg"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/question_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical|start"
        android:padding="18dp"
        android:textColor="@color/test_color_light"
        android:textStyle="bold"
        tools:text="Where do you think Jorge will put this penalty? I'd go left here! Hehehehehehehehehehe super long text" />

    <FrameLayout
        android:layout_width="32dp"
        android:layout_height="32dp">

        <ProgressBar
            android:id="@+id/question_time_progress"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:indeterminate="false"
            android:indeterminateDuration="1"
            android:max="100"
            android:progress="0" />

        <TextView
            android:id="@+id/question_time"
            android:layout_width="26dp"
            android:layout_height="26dp"
            android:layout_gravity="center"
            android:gravity="center"
            android:textColor="@color/test_color_light"
            android:textStyle="bold"
            tools:text="14" />

    </FrameLayout>

</LinearLayout>

buff_answer.xml(将根据该问题的可用答案数量动态地从buff_view.xml注入AnswersContainer中)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="8dp"
    android:background="@drawable/light_bg"
    android:orientation="horizontal"
    tools:ignore="RtlHardcoded">

    <ImageView
        android:id="@+id/answer_image"
        android:layout_width="27dp"
        android:layout_height="27dp"
        android:layout_gravity="center_vertical"
        android:src="@drawable/ic_generic_answer"
        android:padding="4dp" />

    <TextView
        android:id="@+id/answer_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:padding="4dp"
        android:textColor="@color/test_color_dark"
        tools:text="The keeper's right"
        android:textStyle="bold" />
</LinearLayout>

BuffView.kt

class BuffView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null)
    : LinearLayout(context, attrs) {

    private val apiErrorHandler = ApiErrorHandler()
    private val getBuffUseCase = GetBuffUseCase(apiErrorHandler)

    private val intervalsHandler = Handler()

    private val buffView: LinearLayout = inflate(context, R.layout.buff_view, this) as LinearLayout

    private var errorListener: ErrorListener? = null

    private var countDownTimer: CountDownTimer? = null

    private var buffIdCount = 1

    private var getBuffs = false

    fun init() {
        getBuffs = true
        getBuff()
    }

    private fun getBuff() {
        if (!getBuffs) return
        getBuffUseCase.invoke(Params(buffIdCount.toLong()), object : UseCaseResponse<Buff> {
            override fun onSuccess(result: Buff) {
                displayBuff(result)
            }

            override fun onError(errorModel: ErrorModel?) {
                errorListener?.onError( errorModel?.message?: "An error has occurred")
                hideBuff()
            }
        })

        if (buffIdCount < TOTAL_BUFFS ) {
            intervalsHandler.postDelayed({
                buffIdCount++
                getBuff()
                stopCountDownTimer()
            }, REQUEST_BUFF_INTERVAL_TIME)
        }
    }

    private fun displayBuff(buff: Buff) {
        setQuestion(buff.question.title)
        setAuthor(buff.author)
        setAnswer(buff.answers)
        setProgressBar(buff.timeToShow)
        setCloseButton()
        invalidate()
        showBuff()
    }

    private fun setQuestion(questionText: String) {
        question_text.text = questionText
    }

    private fun setAuthor(author: Buff.Author) {
        val firstName = author.firstName
        val lastName = author.lastName
        sender_name.text = "$firstName $lastName"

        Glide.with(buffView)
            .load(author.image)
            .into(sender_image)
    }

    private fun setAnswer(answers: List<Buff.Answer>) {
        val answersContainer = findViewById<LinearLayout>(R.id.answersContainer)
        answersContainer.removeAllViews()
        for(answer in answers) {
            val answerView: View = LayoutInflater.from(answersContainer.context).inflate(
                R.layout.buff_answer,
                answersContainer,
                false
            )

            answer.answerImage?.x0?.url?.let {
                Glide.with(buffView)
                    .load(it)
                    .into(answerView.answer_image)
            }

            answerView.setOnClickListener {
                answerView.background = ContextCompat.getDrawable(context, R.drawable.answer_selected_bg)
                answerView.answer_text.setTextColor(ContextCompat.getColor(context, android.R.color.white))
                //freeze timer
                stopCountDownTimer()
                //hideView() after 2 seconds
                it.postDelayed(Runnable {
                    hideBuff()
                }, HIDE_BUFF_AFTER_SELECTED_ANSWER_DURATION)
            }

            answerView.answer_text?.text = answer.title
            answersContainer.addView(answerView)
        }
    }
...
}

2 个答案:

答案 0 :(得分:3)

您必须将buff_view.xml包含为布局的子级,您可以在其中设置 layout_weight 属性,

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:gravity="bottom">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="horizontal">

        <include layout="@layout/buff_view">
        
    </LinearLayout>

    <View
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="2" />

</LinearLayout>

还可以像这样更改buff视图顶部LinearLayout的宽度和高度约束

<LinearLayout
    android:id="@+id/mainLinearLayout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <include layout="@layout/buff_sender"/>
    <include layout="@layout/buff_question"/>

    <LinearLayout
        android:id="@+id/answersContainer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"/>

</LinearLayout>

编辑 :进度条不可见问题

我认为TextView question_text

有问题

这样更改

<TextView
    android:id="@+id/question_text"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:layout_gravity="center_vertical|start"
    android:padding="18dp"
    android:textColor="@color/test_color_light"
    android:textStyle="bold" />

还可以在 buff_question.xml 中更改主布局,并将其 layout_width 设置为 match_parent

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/dark_bg"
    android:orientation="horizontal">

答案 1 :(得分:2)

使用ConstraintLayout和宽度/高度百分比很容易做到这一点。 确保将实际宽度尺寸设置为0dp(使用百分比值),并确保视图受到适当的约束。

下面将产生此输出

enter image description here

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

<View
    android:background="@color/salmon1"
    android:id="@+id/view1"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHeight_percent=".33"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<View
    android:background="@color/orange1"
    android:id="@+id/view2"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@id/view1" />

</androidx.constraintlayout.widget.ConstraintLayout>
相关问题