TextView Carousel 在滚动时隐藏文本的最后一部分
TextView Carousel hide last part of text when scrolling
我正在尝试使用 TextView
实现轮播,但我遇到了一个奇怪的故障。当向左滚动TextView
时,文本的最后一个字消失,不管多长,滚动时文本的最后一个字appear/disappear,滚动结束后消失。如果 TextView 中只有一个单词,最后一个字符会消失。
这里是例子:
main_fragment.xml
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.main.MainFragment">
<androidx.constraintlayout.motion.widget.MotionLayout
android:id="@+id/motion_carousel"
android:layout_width="0dp"
android:layout_height="100dp"
app:layoutDescription="@xml/carousel_scene"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible">
<TextView
android:id="@+id/text_title_0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/carousel_names_horizontal_margin"
android:background="#000"
android:padding="18dp"
android:textColor="#fff"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/text_title_1"
app:layout_constraintTop_toTopOf="parent"
tools:text="Text 0 disappear" />
<TextView
android:id="@+id/text_title_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/carousel_names_horizontal_margin"
android:background="#000"
android:padding="18dp"
android:textColor="#fff"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/text_title_2"
app:layout_constraintTop_toTopOf="parent"
tools:text="Text 1 disappear" />
<TextView
android:id="@+id/text_title_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#000"
android:padding="18dp"
android:textColor="#fff"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Text 2 disappear" />
<TextView
android:id="@+id/text_title_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/carousel_names_horizontal_margin"
android:background="#000"
android:padding="18dp"
android:textColor="#fff"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/text_title_2"
app:layout_constraintTop_toTopOf="parent"
tools:text="Text 3 disappear" />
<TextView
android:id="@+id/text_title_4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/carousel_names_horizontal_margin"
android:background="#000"
android:padding="18dp"
android:textColor="#fff"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/text_title_3"
app:layout_constraintTop_toTopOf="parent"
tools:text="Text 4 disappear" />
<androidx.constraintlayout.helper.widget.Carousel
android:id="@+id/carousel_scene_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:carousel_backwardTransition="@+id/backward"
app:carousel_firstView="@+id/text_title_2"
app:carousel_forwardTransition="@+id/forward"
app:carousel_nextState="@+id/next"
app:carousel_previousState="@+id/previous"
app:constraint_referenced_ids="text_title_0,text_title_1,text_title_2,text_title_3,text_title_4" />
</androidx.constraintlayout.motion.widget.MotionLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
carousel_scene.xml
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto"
motion:defaultDuration="5000">
<Transition
android:id="@+id/forward"
motion:constraintSetEnd="@+id/next"
motion:constraintSetStart="@id/start"
motion:duration="100">
<OnSwipe
motion:dragDirection="dragLeft"
motion:maxAcceleration="20"
motion:onTouchUp="decelerateAndComplete"
motion:touchAnchorSide="left" />
</Transition>
<Transition
android:id="@+id/backward"
motion:constraintSetEnd="@+id/previous"
motion:constraintSetStart="@+id/start"
motion:duration="100">
<OnSwipe
motion:dragDirection="dragRight"
motion:maxAcceleration="20"
motion:onTouchUp="decelerateAndComplete"
motion:touchAnchorSide="right" />
</Transition>
<ConstraintSet android:id="@+id/previous">
<Constraint
android:id="@+id/text_title_0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/carousel_names_horizontal_margin"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toStartOf="@id/text_title_1"
motion:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="@+id/text_title_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/carousel_names_horizontal_margin"
android:layout_marginEnd="@dimen/carousel_names_horizontal_margin"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="@+id/text_title_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/carousel_names_horizontal_margin"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintStart_toEndOf="@id/text_title_1"
motion:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/text_title_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/carousel_names_horizontal_margin"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toStartOf="@id/text_title_2"
motion:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="@+id/text_title_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/carousel_names_horizontal_margin"
android:layout_marginEnd="@dimen/carousel_names_horizontal_margin"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintHorizontal_bias="0.5"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="@+id/text_title_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/carousel_names_horizontal_margin"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintStart_toEndOf="@id/text_title_2"
motion:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
<ConstraintSet android:id="@+id/next">
<Constraint
android:id="@+id/text_title_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/carousel_names_horizontal_margin"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toStartOf="@id/text_title_3"
motion:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="@+id/text_title_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/carousel_names_horizontal_margin"
android:layout_marginEnd="@dimen/carousel_names_horizontal_margin"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="@+id/text_title_4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/carousel_names_horizontal_margin"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintStart_toEndOf="@id/text_title_3"
motion:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
</MotionScene>
MainFragment.kt
class MainFragment : Fragment() {
companion object {
fun newInstance() = MainFragment()
}
private lateinit var viewModel: MainViewModel
private lateinit var binding: MainFragmentBinding
private val nameList = mutableListOf<String>()
init {
for (i in 0..7){
nameList.add("Text ${i} disappear")
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = MainFragmentBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.carouselSceneTitle.setAdapter(object : Carousel.Adapter {
override fun count(): Int {
return nameList.size
}
override fun populate(view: View, index: Int) {
(view as TextView).apply {
text = nameList[index]
}
}
override fun onNewItem(index: Int) {
}
})
}
}
刚刚意识到在文本后添加一个空 space 可以解决问题,但它更像是一种变通方法,而不是正确的解决方案。
override fun populate(view: View, index: Int) {
(view as TextView).apply {
text = " " + nameList[index] + " "
}
}
我正在尝试使用 TextView
实现轮播,但我遇到了一个奇怪的故障。当向左滚动TextView
时,文本的最后一个字消失,不管多长,滚动时文本的最后一个字appear/disappear,滚动结束后消失。如果 TextView 中只有一个单词,最后一个字符会消失。
这里是例子:
main_fragment.xml
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.main.MainFragment">
<androidx.constraintlayout.motion.widget.MotionLayout
android:id="@+id/motion_carousel"
android:layout_width="0dp"
android:layout_height="100dp"
app:layoutDescription="@xml/carousel_scene"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible">
<TextView
android:id="@+id/text_title_0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/carousel_names_horizontal_margin"
android:background="#000"
android:padding="18dp"
android:textColor="#fff"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/text_title_1"
app:layout_constraintTop_toTopOf="parent"
tools:text="Text 0 disappear" />
<TextView
android:id="@+id/text_title_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/carousel_names_horizontal_margin"
android:background="#000"
android:padding="18dp"
android:textColor="#fff"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/text_title_2"
app:layout_constraintTop_toTopOf="parent"
tools:text="Text 1 disappear" />
<TextView
android:id="@+id/text_title_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#000"
android:padding="18dp"
android:textColor="#fff"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Text 2 disappear" />
<TextView
android:id="@+id/text_title_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/carousel_names_horizontal_margin"
android:background="#000"
android:padding="18dp"
android:textColor="#fff"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/text_title_2"
app:layout_constraintTop_toTopOf="parent"
tools:text="Text 3 disappear" />
<TextView
android:id="@+id/text_title_4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/carousel_names_horizontal_margin"
android:background="#000"
android:padding="18dp"
android:textColor="#fff"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/text_title_3"
app:layout_constraintTop_toTopOf="parent"
tools:text="Text 4 disappear" />
<androidx.constraintlayout.helper.widget.Carousel
android:id="@+id/carousel_scene_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:carousel_backwardTransition="@+id/backward"
app:carousel_firstView="@+id/text_title_2"
app:carousel_forwardTransition="@+id/forward"
app:carousel_nextState="@+id/next"
app:carousel_previousState="@+id/previous"
app:constraint_referenced_ids="text_title_0,text_title_1,text_title_2,text_title_3,text_title_4" />
</androidx.constraintlayout.motion.widget.MotionLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
carousel_scene.xml
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto"
motion:defaultDuration="5000">
<Transition
android:id="@+id/forward"
motion:constraintSetEnd="@+id/next"
motion:constraintSetStart="@id/start"
motion:duration="100">
<OnSwipe
motion:dragDirection="dragLeft"
motion:maxAcceleration="20"
motion:onTouchUp="decelerateAndComplete"
motion:touchAnchorSide="left" />
</Transition>
<Transition
android:id="@+id/backward"
motion:constraintSetEnd="@+id/previous"
motion:constraintSetStart="@+id/start"
motion:duration="100">
<OnSwipe
motion:dragDirection="dragRight"
motion:maxAcceleration="20"
motion:onTouchUp="decelerateAndComplete"
motion:touchAnchorSide="right" />
</Transition>
<ConstraintSet android:id="@+id/previous">
<Constraint
android:id="@+id/text_title_0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/carousel_names_horizontal_margin"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toStartOf="@id/text_title_1"
motion:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="@+id/text_title_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/carousel_names_horizontal_margin"
android:layout_marginEnd="@dimen/carousel_names_horizontal_margin"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="@+id/text_title_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/carousel_names_horizontal_margin"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintStart_toEndOf="@id/text_title_1"
motion:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/text_title_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/carousel_names_horizontal_margin"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toStartOf="@id/text_title_2"
motion:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="@+id/text_title_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/carousel_names_horizontal_margin"
android:layout_marginEnd="@dimen/carousel_names_horizontal_margin"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintHorizontal_bias="0.5"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="@+id/text_title_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/carousel_names_horizontal_margin"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintStart_toEndOf="@id/text_title_2"
motion:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
<ConstraintSet android:id="@+id/next">
<Constraint
android:id="@+id/text_title_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/carousel_names_horizontal_margin"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toStartOf="@id/text_title_3"
motion:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="@+id/text_title_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/carousel_names_horizontal_margin"
android:layout_marginEnd="@dimen/carousel_names_horizontal_margin"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="@+id/text_title_4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/carousel_names_horizontal_margin"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintStart_toEndOf="@id/text_title_3"
motion:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
</MotionScene>
MainFragment.kt
class MainFragment : Fragment() {
companion object {
fun newInstance() = MainFragment()
}
private lateinit var viewModel: MainViewModel
private lateinit var binding: MainFragmentBinding
private val nameList = mutableListOf<String>()
init {
for (i in 0..7){
nameList.add("Text ${i} disappear")
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = MainFragmentBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.carouselSceneTitle.setAdapter(object : Carousel.Adapter {
override fun count(): Int {
return nameList.size
}
override fun populate(view: View, index: Int) {
(view as TextView).apply {
text = nameList[index]
}
}
override fun onNewItem(index: Int) {
}
})
}
}
刚刚意识到在文本后添加一个空 space 可以解决问题,但它更像是一种变通方法,而不是正确的解决方案。
override fun populate(view: View, index: Int) {
(view as TextView).apply {
text = " " + nameList[index] + " "
}
}