在适配器中将一个字符串显示在多个TextView中。

huangapple go评论78阅读模式
英文:

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 = &quot;&quot;;
            option = message.getMessage();
            for ( DialogNodeOutputOptionsElement r : message.getOptions() ){
                 option += r.getLabel()+&quot;&lt;br/&gt;&quot;;
                ((ViewHolder) holder).message.setText(Html.fromHtml(option));
                // new TextView for next Option

The whole ChatAdapter looks like this:

    public class ChatAdapter extends RecyclerView.Adapter&lt;RecyclerView.ViewHolder&gt; {

    protected Activity activity;
    private int SELF = 100;
    private ArrayList&lt;Message&gt; messageArrayList;



    public ChatAdapter(ArrayList&lt;Message&gt; 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 &amp;&amp; message.getId().equals(&quot;1&quot;)) {
            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()+&quot;&lt;br/&gt;&quot;));

                    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 = &quot;&quot;;
                option = message.getMessage();
                for ( DialogNodeOutputOptionsElement r : message.getOptions() ){
                     option += r.getLabel()+&quot;&lt;br/&gt;&quot;;
                    ((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:

   &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:id=&quot;@+id/linear&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;wrap_content&quot;
    android:orientation=&quot;horizontal&quot;&gt;

    &lt;android.support.v7.widget.AppCompatImageView
        android:layout_width=&quot;54dp&quot;
        android:layout_height=&quot;match_parent&quot;
        android:layout_marginLeft=&quot;5dp&quot;
        android:src=&quot;@mipmap/new_face&quot; /&gt;


    &lt;TextView
        android:id=&quot;@+id/message&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_alignParentLeft=&quot;true&quot;
        android:layout_marginLeft=&quot;5dp&quot;
        android:layout_marginTop=&quot;5dp&quot;
        android:layout_marginRight=&quot;5dp&quot;
        android:layout_marginBottom=&quot;10dp&quot;
        android:autoLink=&quot;web&quot;
        android:background=&quot;@drawable/bg_bubble_watbot&quot;
        android:fontFamily=&quot;sans-serif&quot;
        android:textColor=&quot;@android:color/black&quot;
        android:textIsSelectable=&quot;true&quot;
        android:textSize=&quot;14sp&quot; /&gt;

    &lt;ImageView
        android:id=&quot;@+id/image&quot;
        android:layout_width=&quot;fill_parent&quot;
        android:layout_height=&quot;wrap_content&quot;
        /&gt;



&lt;/LinearLayout&gt;

Contex Error

App picture after working code

答案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 TextViews:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
android:id=&quot;@+id/linear&quot;... &gt;

    &lt;android.support.v7.widget.AppCompatImageView ... /&gt;

    &lt;TextView ... /&gt;

    &lt;LinearLayout android:id=&quot;@+id/optionsContainer&quot;
                  android:layout_width=&quot;match_parent&quot;
                  android:layout_height=&quot;wrap_content&quot;
                  android:background=&quot;@drawable/bg_bubble_watbot&quot;
                  android:orientation=&quot;vertical&quot; /&gt;

    &lt;ImageView .../&gt;

&lt;/LinearLayout&gt;

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(&quot;#0000ff&quot;);
    // 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, &quot;Link clicked&quot;, Toast.LENGTH_SHORT).show();
            // add here what the click should do
        }
    });
    return tv;
}

huangapple
  • 本文由 发表于 2020年8月20日 19:18:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/63503903.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定