英文:
Show a string in multiple TextViews in adapter
问题
以下是翻译后的内容:
目前我的应用在一个单独的 TextView 中显示了4个选项(我想要使它们可点击)。目前的显示效果如下(即最后一个消息气泡):应用图片
与上述情况不同,我想要将这些选项作为4个单独的 TextView 来显示,就像这个例子中的效果。我研究了多种解决方案,但是因为我正在使用 RecyclerView.Adapter
,所以它们都不适用于我。以下是相关的部分代码:
case OPTION:
String option = "";
option = message.getMessage();
for ( DialogNodeOutputOptionsElement r : message.getOptions() ){
option += r.getLabel()+"<br/>";
((ViewHolder) holder).message.setText(Html.fromHtml(option));
// 下一个选项的新 TextView
}
break;
整个 ChatAdapter 的代码如下:
public class ChatAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
protected Activity activity;
private int SELF = 100;
private ArrayList<Message> messageArrayList;
public ChatAdapter(ArrayList<Message> messageArrayList) {
this.messageArrayList = messageArrayList;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// ...(与您提供的代码相同)
}
@Override
public int getItemViewType(int position) {
// ...(与您提供的代码相同)
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
// ...(与您提供的代码相同)
}
@Override
public int getItemCount() {
return messageArrayList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView message;
ImageView image;
public ViewHolder(View view) {
// ...(与您提供的代码相同)
}
}
}
XML 文件如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/linear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- ...(与您提供的代码相同) -->
<TextView
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="10dp"
android:autoLink="web"
android:background="@drawable/bg_bubble_watbot"
android:fontFamily="sans-serif"
android:textColor="@android:color/black"
android:textIsSelectable="true"
android:textSize="14sp" />
<!-- ...(与您提供的代码相同) -->
</LinearLayout>
英文:
My App currently displays 4 options (which I want to make clickable) in a single TextView. At the moment, it looks like this (i.e. last message bubble): app picture
Instead of the above, I want to have those options as 4 separate TextViews, like in this example. I researched multiple solutions, but none of them worked for me, because I am using RecyclerView.Adapter
. Here is the relevant part:
case OPTION:
String option = "";
option = message.getMessage();
for ( DialogNodeOutputOptionsElement r : message.getOptions() ){
option += r.getLabel()+"<br/>";
((ViewHolder) holder).message.setText(Html.fromHtml(option));
// new TextView for next Option
The whole ChatAdapter looks like this:
public class ChatAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
protected Activity activity;
private int SELF = 100;
private ArrayList<Message> messageArrayList;
public ChatAdapter(ArrayList<Message> messageArrayList) {
this.messageArrayList = messageArrayList;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView;
// view type is to identify where to render the chat message
// left or right
if (viewType == SELF) {
// self message
itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.chat_item_self, parent, false);
} else {
// WatBot message
itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.chat_item_watson, parent, false);
}
return new ViewHolder(itemView);
}
@Override
public int getItemViewType(int position) {
Message message = messageArrayList.get(position);
if (message.getId() != null && message.getId().equals("1")) {
return SELF;
}
return position;
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
Message message = messageArrayList.get(position);
switch (message.type) {
case TEXT:
((ViewHolder) holder).message.setText(Html.fromHtml(message.getMessage()+"<br/>"));
break;
case IMAGE:
((ViewHolder) holder).message.setVisibility(View.GONE);
ImageView iv = ((ViewHolder) holder).image;
Glide
.with(iv.getContext())
.load(message.getUrl())
.into(iv);
break;
case OPTION:
String option = "";
option = message.getMessage();
for ( DialogNodeOutputOptionsElement r : message.getOptions() ){
option += r.getLabel()+"<br/>";
((ViewHolder) holder).message.setText(Html.fromHtml(option));
// new TextView for next Option
}
break;
case PAUSE:break;
}
}
@Override
public int getItemCount() {
return messageArrayList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView message;
ImageView image;
public ViewHolder(View view) {
super(view);
message = (TextView) itemView.findViewById(R.id.message);
image = (ImageView) itemView.findViewById(R.id.image);
//TODO: Uncomment this if you want to use a custom Font
}
}
}
and the XML looks like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/linear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<android.support.v7.widget.AppCompatImageView
android:layout_width="54dp"
android:layout_height="match_parent"
android:layout_marginLeft="5dp"
android:src="@mipmap/new_face" />
<TextView
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="10dp"
android:autoLink="web"
android:background="@drawable/bg_bubble_watbot"
android:fontFamily="sans-serif"
android:textColor="@android:color/black"
android:textIsSelectable="true"
android:textSize="14sp" />
<ImageView
android:id="@+id/image"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
答案1
得分: 0
在您的布局中添加一个用于放置要添加的 TextView
的容器:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/linear"...
<androidx.appcompat.widget.AppCompatImageView ... />
<TextView ... />
<LinearLayout
android:id="@+id/optionsContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_bubble_watbot"
android:orientation="vertical" />
<ImageView .../>
</LinearLayout>
然后,更新您的 ViewHolder
以引用该容器:
public class ViewHolder extends RecyclerView.ViewHolder {
...
LinearLayout optionsContainer;
public ViewHolder(View view) {
super(view);
...
optionsContainer = (LinearLayout) itemView.findViewById(R.id.optionsContainer);
}
}
接下来,在您的 OPTION
案例中:
TextView tv = ((ViewHolder) holder).message;
tv.setVisibility(View.GONE);
LinearLayout optionsContainer = ((ViewHolder) holder).optionsContainer;
TextView messageTextView = createTextView(message.getMessage(), optionsContainer.getContext());
for (DialogNodeOutputOptionsElement r : message.getOptions()) {
// 检查 r.getLabel() 是否真的返回 HTML 字符串
// 如果不是,您将需要用 HTML 标签将其包围起来,以便稍后可以点击
String option = r.getLabel();
TextView optionTextView = createTextView(option, optionsContainer.getContext());
// 将创建的 textView 添加到容器中
optionsContainer.addView(optionTextView);
}
在适配器中实现 createTextView()
函数:
private TextView createTextView(String text, Context context) {
TextView tv = new TextView(context);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
);
tv.setLayoutParams(params);
tv.setTextSize((float) 15);
tv.setText(text);
int blueColor = Color.parseColor("#0000ff");
// 将文本设为蓝色
tv.setTextColor(blueColor);
// 添加下划线
tv.setPaintFlags(tv.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(context, "链接被点击", Toast.LENGTH_SHORT).show();
// 在此添加点击后的操作
}
});
return tv;
}
英文:
Try following:
Inside your layout, add a container for your to-be-added TextView
s:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/linear"... >
<android.support.v7.widget.AppCompatImageView ... />
<TextView ... />
<LinearLayout android:id="@+id/optionsContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_bubble_watbot"
android:orientation="vertical" />
<ImageView .../>
</LinearLayout>
Then, update your ViewHolder
to reference the container:
public class ViewHolder extends RecyclerView.ViewHolder {
...
LinearLayout optionsContainer;
public ViewHolder(View view) {
super(view);
...
optionsContainer = (LinearLayout) itemView.findViewById(R.id.optionsContainer);
}
}
Then, in your OPTION
case:
TextView tv = ((ViewHolder) holder).message;
tv.setVisibility(View.GONE));
LinearLayout optionsContainer = ((ViewHolder) holder).optionsContainer;
TextView messageTextView = createTextView(message.getMessage(), optionsContainer.getContext());
for ( DialogNodeOutputOptionsElement r : message.getOptions() ) {
// you should check if r.getLabel() really returns a HTML string
// if not, you will have to enclose it with html tags to make it clickable later
String option = r.getLabel();
TextView optionTextView = createTextView(option, optionsContainer.getContext());
// add the created textView to our container
optionsContainer.addView(optionTextView);
}
Implement the createTextView()
function inside your adapter:
private TextView createTextView(String text, Context context) {
TextView tv = new TextView(context);
LinearLayout.LayoutParams params=new LinearLayout.LayoutParams
((int) LinearLayout.LayoutParams.WRAP_CONTENT,(int) LinearLayout.LayoutParams.WRAP_CONTENT);
tv.setLayoutParams(params);
tv.setTextSize((float) 15);
tv.setText(text);
int blueColor = Color.parseColor("#0000ff");
// make text blue
tv.setTextColor(blueColor);
// make text underline
tv.setPaintFlags(tv.getPaintFlags()| Paint.UNDERLINE_TEXT_FLAG);
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(context, "Link clicked", Toast.LENGTH_SHORT).show();
// add here what the click should do
}
});
return tv;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论