【问题标题】:Changing TextSize of a TextView inside a ListView at runtime在运行时更改 ListView 内 TextView 的 TextSize
【发布时间】:2013-05-08 07:10:25
【问题描述】:

我有一个ListView,它使用自定义SimpleCursorAdapter 来显示信息。每个ListView 行有三个TextView 项目。

由于应用程序的性质,读者可能希望也可能不希望更改字体大小以方便阅读显示在行项目上的文本。

我想要完成的是一种更新此TextView 项目的文本大小的方法,而无需从bindView() 进行。

这是我目前的做法:

第一步:通知适配器应该更改 textSize。

public void setAdjustTextSize(int size) {       
    switch (size) {
    case ArticleViewFragment.FONT_SIZE_SMALL:
        mTitleTextSizeRes = R.dimen.title_size_small;
        mCategoryTextSizeRes = R.dimen.description_size_small;
        mDescripTextSizeRes = R.dimen.description_size_small;
        break;
    case ArticleViewFragment.FONT_SIZE_MEDIUM:
        mTitleTextSizeRes = R.dimen.title_size_medium;
        mCategoryTextSizeRes = R.dimen.description_size_medium;
        mDescripTextSizeRes = R.dimen.description_size_medium;
        break;
    case ArticleViewFragment.FONT_SIZE_LARGE:
        mTitleTextSizeRes = R.dimen.title_size_large;
        mCategoryTextSizeRes = R.dimen.description_size_large;
        mDescripTextSizeRes = R.dimen.description_size_large;
        break;
    case ArticleViewFragment.FONT_SIZE_EXTRA_LARGE:
        mTitleTextSizeRes = R.dimen.title_size_extra_large;
        mCategoryTextSizeRes = R.dimen.description_size_extra_large;
        mDescripTextSizeRes = R.dimen.description_size_extra_large;
        break;
    default:
        break;
    }
}

mTitleTextSizeRes、mCategoryTextSizeRes 和 mDescripTextSizeRes 是自定义适配器的实例变量。

第二步:在 bindView() 期间设置 textSize。

@Override
public void bindView(View view, Context arg1, Cursor arg2) {
    ViewHolder mHolder = (ViewHolder) view.getTag();
     //Some other initialization
    mHolder.category.setTextSize(TypedValue.COMPLEX_UNIT_PX, mResources.getDimension(mCategoryTextSizeRes));
    mHolder.title.setTextSize(TypedValue.COMPLEX_UNIT_PX, mResources.getDimension(mTitleTextSizeRes));
    mHolder.description.setTextSize(TypedValue.COMPLEX_UNIT_PX, mResources.getDimension(mDescripTextSizeRes));
}

现在,这行得通,是的,但有几点我想争论:

1- 我在运行时更改 TextSize 的事实每次重用 convertView 时。最好通过onNewView 执行此操作,然后convertViews 将已经使用新的设置大小。但是,尝试这样做会失败,因为大多数时候,适配器已经创建,并且视图已经存在。

2 - 事实上,由于代码在bindView 上运行,现有视图不会立即看到更改,并且在滚动过程中的某个时间点,用户将看到一些具有旧文本大小的视图,和一些新的文本大小。 Example Image attached.

话虽如此,我希望我可以完成一些类似重新初始化适配器的操作,但我不知道该怎么做,除了可能从头开始创建适配器。 我尝试调用 notifyDataSetChanged,但什么也没做

有什么想法吗?

【问题讨论】:

  • 发布您的自定义光标适配器。当我尝试在自定义列表适配器中修改视图的文本大小时,我会在适配器内部进行修改。

标签: android textview simplecursoradapter text-size


【解决方案1】:

尝试将自定义适配器的 getView() 更改为如下内容:

public View getView(int position, View convertView, ViewGroup parent)
{
    View view = super.getView(position, convertView, parent);
    TextView tv = (TextView)view;

    // NOTE: textSize is set in the custom adapter's constructor
    // int textSize

    tv.setTextSize(textSize);

    return view;
}

【讨论】:

    【解决方案2】:

    创建您自己的适配器非常容易,尤其是当您只使用每行的 textView 时。

    您只需覆盖 getView() 方法并在它不为 null 时重新使用 convertView,或者在它为 null 时为该行膨胀一个新视图(并创建它的 viewholder 以作为标签放置)。

    然后,您使用视图的 viewHolder 将 textViews 更新为新大小。

    当用户改变了字体大小的偏好时,只需调用 notifyDataSetChanged。

    如需更熟悉 listView 和适配器,请观看“the world of listView”。

    【讨论】:

      【解决方案3】:

      显然我不清楚我使用的是我自己的SimpleCursorAdapter 实现,@MarsAtomic 和@android 开发人员都建议我覆盖getView(),但是,当使用SimpleCursorAdapter 时,你不会,你覆盖onNewView()onBindView()

      我最终想要避免的只是从头开始重新创建适配器,并在 onNewView() 期间设置 TextSize。我对结果非常满意,因为这仅通过设置新视图的大小来最大限度地减少对textview.setTextSize(size) 的调用量。

      第一步,在我的活动中,在 onResume 期间检查字体大小是否改变,如果改变,从头开始重新创建适配器:

      final int oldSize = mCurFontSize; 
      mCurFontSize = Integer.valueOf(mPreferences.getString(getString(R.string.pref_key_font_size), "0"));
      if (oldSize != mCurFontSize) {
          //Only re-do the adapter if needed
          Constants.logMessage("re-creating adapter");
          mArticleAdapter = new CursorListAdapter(Home.this, R.layout.list_item,
          mCursor, FROM, TO, 0, mCurFontSize);
          mArticlesListView.setAdapter(mArticleAdapter);
          }
      }   
      

      第二步,在适配器构造函数上,将字体大小值设置为实例变量。

      public CursorListAdapter(Context context, int layout, Cursor c,
              String[] from, int[] to, int flags, int textSize) {
          super(context, layout, c, from, to, flags);
          mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
          mRootLayout = layout;
          mResources = context.getResources();
          setAdjustTextSize(textSize);
      }   
      

      setAdjustTextSize 的作用是:

      public void setAdjustTextSize(int size) {       
          mTextSize = size;
          switch (size) {
          case ArticleViewFragment.FONT_SIZE_SMALL:
              mTitleTextSizeRes = R.dimen.title_size_small;
              mCategoryTextSizeRes = R.dimen.description_size_small;
              mDescripTextSizeRes = R.dimen.description_size_small;
              break;
          case ArticleViewFragment.FONT_SIZE_MEDIUM:
              mTitleTextSizeRes = R.dimen.title_size_medium;
              mCategoryTextSizeRes = R.dimen.description_size_medium;
              mDescripTextSizeRes = R.dimen.description_size_medium;
              break;
          case ArticleViewFragment.FONT_SIZE_LARGE:           
              mTitleTextSizeRes = R.dimen.title_size_large;
              mCategoryTextSizeRes = R.dimen.description_size_large;
              mDescripTextSizeRes = R.dimen.description_size_large;
              break;
          case ArticleViewFragment.FONT_SIZE_EXTRA_LARGE:
              mTitleTextSizeRes = R.dimen.title_size_extra_large;
              mCategoryTextSizeRes = R.dimen.description_size_extra_large;
              mDescripTextSizeRes = R.dimen.description_size_extra_large;
              break;
          default:
              break;
          }
      }   
      

      第三步:onNewView()期间设置文字大小。

      @Override
      public View newView(Context context, Cursor cursor, ViewGroup parent) {
          View container = mInflater.inflate(mRootLayout, null);
      
          ViewHolder mHolder = new ViewHolder();
      
          mHolder.category = (TextView) container.findViewById(R.id.article_category);
          mHolder.title = (TextView) container.findViewById(R.id.article_title);
          mHolder.description = (TextView) container.findViewById(R.id.article_descrp);
          mHolder.image = (ImageView) container.findViewById(R.id.article_image);
      
          mHolder.category.setTextSize(TypedValue.COMPLEX_UNIT_PX, mResources.getDimension(mCategoryTextSizeRes));
          mHolder.title.setTextSize(TypedValue.COMPLEX_UNIT_PX, mResources.getDimension(mTitleTextSizeRes));
          mHolder.description.setTextSize(TypedValue.COMPLEX_UNIT_PX, mResources.getDimension(mDescripTextSizeRes));
      
          container.setTag(mHolder);
      
          return container;       
      }
      

      就是这样。它有效,在适配器的生命周期中它不会多次调用 setTextSize,我只在字体大小发生变化时重新创建适配器,我们都很高兴。

      【讨论】:

        猜你喜欢
        • 2018-06-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-05
        相关资源
        最近更新 更多