I'm having an issue where .measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
somehow alters the view's state.
I've set up a view which listens to the onClick
event and performs the .measure
. Note that when I perform this directly in onCreate
, it does not occur.
I expect that this code should only re-draw my textView
with green color, not change any position.
Simple view:
Same view after clicking it. Notice how the position is off:
Activity:
class Main2Activity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main2)
setSupportActionBar(toolbar)
val root = findViewById<ConstraintLayout>(R.id.foo)
val tv = root.findViewById<TextView>(R.id.bar)
tv.setOnClickListener {
tv.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
tv.setTextColor(resources.getColor(R.color.green))
}
}
}
Layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="io.flogging.activities.Main2Activity"
android:id="@+id/foo"
tools:showIn="@layout/activity_main2">
<TextView
android:id="@+id/bar"
android:background="@color/colorAccent"
android:layout_width="match_parent"
android:gravity="center"
android:padding="10dp"
android:minLines="2"
android:text="Please let me be in center"
android:layout_height="100dp" />
</android.support.constraint.ConstraintLayout>
You probably don't want to be calling
measure()
in the first place. The system should take care of that for you. Just go ahead and delete that call.If you've left something out of the question, and you absolutely must call
measure()
, then you need to make sure that you pass the correct parameters. The documentation forView.measure()
specifies that you must pass "measure specs", notLayoutParams
constants. That is, instead of what you have, you would pass something that looked like this:Both
View.MeasureSpec.makeMeasureSpec(200, View.MeasureSpec.EXACTLY)
andViewGroup.LayoutParams.MATCH_PARENT
are of typeint
, which is why the compiler doesn't complain and the app doesn't crash. But you can't just pass any oldint
to this method.Note, however, that the explicit purpose of this call is to change the layout of the view. So if you call measure, then you're going to change the view's layout, because that is what it does.
I don't know for sure, but I suspect that this is because your manual call to
measure()
inonCreate()
comes before a system-intiated call tomeasure()
during view layout, so your modified structure gets thrown out. When you do it in anOnClickListener
instead, then your manual call comes second, and overrides the system-initiated call.