【问题标题】:Android DataBinding/Recyclerview - set custom span for textview with SpannableBuilderAndroid DataBinding/Recyclerview - 使用 SpannableBuilder 为 textview 设置自定义跨度
【发布时间】:2017-07-10 09:18:14
【问题描述】:

我正在项目中从旧的ListView 迁移到RecyclerView。我决定使用数据绑定来绑定列表值,但是在为我的文本框设置自定义文本跨度时遇到了一些问题。

请看这段代码(这是用旧的 ListBox 适配器完成的):

@Override
public View getView(int position, @Nullable View convertView, ViewGroup parent) {
    ...

    Typeface tf = Typeface.createFromAsset(convertView.getContext().getAssets(), "fonts/fontawesome.ttf");
    SpannableStringBuilder textCategory = new SpannableStringBuilder((item != null ? item.getCategoryIconName() : null) + "     " + item.getCategoryName());
    textCategory.setSpan (new CustomTypefaceSpan("", tf), 0, 1, Spanned.SPAN_EXCLUSIVE_INCLUSIVE);

    viewHolder.eventCategory.setText(textCategory);

    ...
}

基本上,我的CustomTypeFaceSpan 用于为单个TextView 设置多种字体。如何使用数据绑定实现相同的功能?可以使用BindingAdapter吗?

我的尝试:

<variable name="categoryText" type="String"/>
<variable name="data" type="Event"/>

<TextView
                android:id="@+id/event_category_text"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="32dp"
                android:layout_marginRight="8dp"
                android:layout_marginTop="16dp"
                android:paddingBottom="3dp"
                android:paddingTop="3dp"
                android:text="@{data.categoryIconName + data.categoryName}"
                android:textAppearance="@style/TextAppearance.AppCompat.Body2"
                android:textColor="@color/colorEventCategoryText"
                app:customFunction="@{categoryText}"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent"/>

绑定适配器:

@BindingAdapter({"customFunction"})
    public static void setSpan(TextView textView, String categoryText)
    {
        Typeface tf = Typeface.createFromAsset(textView.getContext().getAssets(), "fonts/fontawesome.ttf");
        SpannableStringBuilder textCategory = new SpannableStringBuilder(categoryText);
        textCategory.setSpan (new CustomTypefaceSpan("", tf), 0, 1, Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        textView.setText(textCategory);
    }

问题:categoryText 始终为空。有任何想法吗? TextView 已正确绑定,因为没有自定义功能,它会按应有的方式显示文本。

我的列表适配器:

public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ViewHolder>
{
    public List<Event> events = null;
    private final ListFragment.OnFragmentInteractionListener mListener;

    public ListAdapter(List<Event> events, ListFragment.OnFragmentInteractionListener mListener)
    {
        this.events = events;
        this.mListener = mListener;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType)
    {

        LayoutInflater layoutInflater = LayoutInflater.from(viewGroup.getContext());
        ViewDataBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.cell, viewGroup, false);
        return new ViewHolder(binding);
    }


    @Override
    public void onBindViewHolder(ViewHolder viewHolder, final int position)
    {

        final Event event = events.get(position);
        viewHolder.bind(event);

        viewHolder.binding.getRoot().setOnClickListener(v ->
        {
            if (null != mListener)
            {
                mListener.onFragmentInteraction(event);
            }
        });
    }

    @Override
    public int getItemCount()
    {
        return events.size();
    }


    public static class ViewHolder extends RecyclerView.ViewHolder
    {
        private final ViewDataBinding binding;

        public ViewHolder(ViewDataBinding binding)
        {
            super(binding.getRoot());
            this.binding = binding;
        }

        public void bind(Object obj)
        {
            binding.setVariable(BR.data,obj);
            binding.executePendingBindings();
        }
    }
}

【问题讨论】:

    标签: java android android-recyclerview android-databinding spannablestringbuilder


    【解决方案1】:

    使用自定义属性,如:

    在 xml 中:

    <data>
      <variable
          name="name"
          type="String"></variable>
    </data>
    ........
      <TextView
         android:id="@+id/textView2"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_margin="20dp"
         app:customFunction="@{name}"
        />
    

    在活动类中

    .............
    ActivityMainBinding binding = DataBindingUtil........
    binding.setName("Something");
    ...................
    @BindingAdapter("customFunction")
    public static void myCustomFunction(TextView textView, String name){
        Log.d("MainActivity", "custom function called");
        String nameCaps = name.toUpperCase();
        textView.setText(nameCaps);
    }
    

    myCustomFunction(..) 在从 xml 创建 Textview 时会被调用。您可以使用自定义函数将 Span 设置为您的视图。

    【讨论】:

    • 调用了自定义函数,但 name 参数对我来说始终为空。我更新了我的问题。不是不是activity绑定,是RecyclerView(不知道有没有关系)
    • 通过 binding.setCategoryText("value") 方法为您的 categoryText 变量设置值。 setCategoryText() 方法将在您在 xml 中的变量标记中声明变量时自动创建
    • 查看此链接了解更多详情medium.com/google-developers/…
    • 在哪里放binding.setCategoryText("value") 你的意思是ViewHolder?我已经阅读了您发布的文档,但我仍然无法弄清楚出了什么问题。问题更新,添加列表适配器代码
    • 将该代码放在“ViewDataBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.cell, viewGroup, false);”之后的 onCreateViewHolder() 函数中这一行
    猜你喜欢
    • 1970-01-01
    • 2017-07-16
    • 2018-09-16
    • 1970-01-01
    • 2017-09-17
    • 2018-06-23
    • 2021-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多