在运行时更改ListView内TextView的TextSize

时间:2013-05-07 22:20:41

标签: android textview simplecursoradapter text-size

我有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-每次重新使用convertView时,我都会在运行时更改TextSize 。最好通过onNewView执行此操作,然后convertViews将使用新的设置大小。但是,尝试这样做会失败,因为大多数情况下,适配器已经创建,并且视图已经存在。

2 - 由于代码在bindView上运行,因此现有视图不会立即看到更改,并且在滚动期间的某个时刻,用户将使用旧文本查看一些视图大小,有些是新的文字大小。 Example Image attached.

说到这一点,我希望我可以调整一些重新初始化适配器的东西,但我不知道怎么做,除了从头开始创建适配器。 我尝试调用notifyDataSetChanged,但没有做任何事情

有什么想法吗?

3 个答案:

答案 0 :(得分:0)

尝试将自定义适配器的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;
}

答案 1 :(得分:0)

创建自己的适配器非常简单,特别是如果您使用的只是每行的textViews。

你只需覆盖getView()方法并重新使用convertView(如果它不为null),或者为该行的新视图充气(如果它为null)(并创建其viewholder作为标记)。

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

当用户更改了字体大小的首选项时,只需调用notifyDataSetChanged。

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

答案 2 :(得分:0)

显然我不清楚我是否正在使用我自己的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,我只在字体大小改变时重新创建适配器,我们都很高兴。