动态 TextView 无法正确显示
Posted
技术标签:
【中文标题】动态 TextView 无法正确显示【英文标题】:Dynamic TextView not displaying properly 【发布时间】:2022-01-01 20:29:20 【问题描述】:我正在循环中动态生成一些 TextView。它们正在显示,但我无法在它们之间制造差距。它们显示为一行而不是单独的行。
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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_
android:layout_
android:fitsSystemWindows="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_
android:layout_
>
<LinearLayout
android:id="@+id/ll"
android:layout_
android:layout_
android:paddingLeft="18dp"
android:paddingRight="18dp"
android:paddingTop="60dp"
android:paddingBottom="@dimen/activity_vertical_margin"
android:focusableInTouchMode="true"
android:orientation="vertical">
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
tviewlayout.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:background="@color/light"
android:textAlignment="gravity"
android:padding="10dp"
android:layout_margin="10dp"
android:textSize="20sp" />
Java 代码
LinearLayout linearLayout = (LinearLayout) binding.ll;
for (int i=0; i<arrSplit.length; i++)
TextView tv = (TextView)getLayoutInflater().inflate(R.layout.tviewlayout, null);
tv.setText(arrSplit[i]);
tv.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
linearLayout.addView(tv);
【问题讨论】:
如果你将任何东西放入一个约束布局(在本例中是你的 LinearLayout),你需要定义它的约束。将 LL 的所有 4 个约束设置为“父”,事情应该会更好。还将 LL 的layout_width
和 layout_height
设置为“0dp”。这告诉 Android 它应该使用给定的约束。
移除约束布局!
你能提供一张你得到的照片吗
@Zain 我添加了一张照片
那么,我认为每个训练行都是LinearLayout
中的TextView
?如果是这样,这是意料之中的......你能展示你期望看到的东西吗?所以不会有混乱
【参考方案1】:
我建议将 recylerview 用于此类目的。它更加高效和动态。示例在 Kotlin
<?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/consRideInfo"
android:layout_
android:layout_
android:layout_margin="@dimen/10dp"
android:padding="@dimen/10dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/incActionBar">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rcvList"
android:layout_
android:layout_
android:paddingBottom="0dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:itemCount="3"
tools:listitem="@layout/row_item" />
</androidx.constraintlayout.widget.ConstraintLayout>
关于Activity定义适配器
private var adapter: GeneralAdapter<DataModel, MainActivity>? = null
private val list: ArrayList<DataModel> = ArrayList()
在 onCreate 中
adapter = GeneralAdapter(R.layout.row_item, list, this)
binding.rcvList.adapter = adapter
并创建适配器用于显示
class GeneralAdapter<D, F>(
val layoutId: Int,
private val arrayList: ArrayList<D>,
val listener: F
) : RecyclerView.Adapter<GeneralAdapter.GeneralHolder<D, F>>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GeneralHolder<D, F>
val layoutInflater = LayoutInflater.from(parent.context)
val binding: ViewDataBinding =
DataBindingUtil.inflate(layoutInflater, layoutId, parent, false)
return GeneralHolder(binding, listener)
override fun getItemCount(): Int = arrayList.size
override fun onBindViewHolder(holder: GeneralHolder<D, F>, position: Int)
holder.bind(arrayList[position])
class GeneralHolder<D, F>(
private val binding: ViewDataBinding,
val listener: F
) :
RecyclerView.ViewHolder(binding.root)
fun bind(data: D)
binding.setVariable(BR.item, data)
binding.setVariable(BR.presenter, listener)
binding.executePendingBindings()
【讨论】:
【参考方案2】:我想在每个 TextView 之间创建间隙,以便它们看起来是分开的。现在都被蓝色背景覆盖了
您可以为每个TextViews
添加一个以像素为单位的边距:
LinearLayout linearLayout = (LinearLayout) binding.ll;
for (int i=0; i<arrSplit.length; i++)
TextView tv = (TextView)getLayoutInflater().inflate(R.layout.tviewlayout, null);
tv.setText(arrSplit[i]);
tv.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) tv.getLayoutParams();
params.bottomMargin = (int) getPx(100); // adding 100dp gap between TextViews
linearLayout.addView(tv);
/*
* Convert dp value to pixel
* */
private float getPx(float dp)
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dp,
getResources().getDisplayMetrics());
更新
你能告诉我如何使用 RecyclerView 实现同样的效果吗?
这是一个演示:
main_activity.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rvList"
android:layout_
android:layout_
tools:context=".MainActivity" />
list_item.xml:包含您的TextView
的模板
使用android:layout_marginBottom
在两个连续的 TextView 之间添加所需的边距
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tvColorName"
android:layout_
android:layout_
android:layout_marginBottom="32dp"
android:textSize="18sp" />
适配器:
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.CustomViewHolder>
private List<String> mColors;
// Constructor
RecyclerAdapter(List<String> colors)
this.mColors = colors;
@NonNull
@Override
public CustomViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i)
View listItem = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item, parent, false);
return new CustomViewHolder(listItem);
@Override
public void onBindViewHolder(@NonNull CustomViewHolder holder, int position)
String color = mColors.get(position);
holder.tvColorName.setText(color);
@Override
public int getItemCount()
return mColors.size();
class CustomViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener
TextView tvColorName;
CustomViewHolder(@NonNull View listItem)
super(listItem);
// caching views
tvColorName = listItem.findViewById(R.id.tvColorName);
活动:
public class MainActivity extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Building RecyclerView
RecyclerView recyclerView = findViewById(R.id.rvList);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
// Building RecyclerAdapter
RecyclerAdapter adapter = new RecyclerAdapter(this, getColors());
recyclerView.setAdapter(adapter);
private ArrayList<String> getColors()
ArrayList<String> colors = new ArrayList<>();
colors.add("Red");
colors.add("White");
colors.add("Green");
colors.add("Purple");
colors.add("Yellow");
colors.add("Blue");
colors.add("Black");
colors.add("Brown");
colors.add("Magenta");
colors.add("Cyan");
colors.add("Gray");
colors.add("Orange");
return colors;
【讨论】:
但我建议将此方法更改为RecyclerView
以具有回收视图功能
你能告诉我如何使用 RecyclerView 实现同样的效果吗?
@John Sure.. 请检查更新的答案以上是关于动态 TextView 无法正确显示的主要内容,如果未能解决你的问题,请参考以下文章
java 添加指向TextView的链接。 Linkify。字体:https://stackoverflow.com/questions/4746293/android-linkify-textvie