Android 在运行时更改ListView中TextView的TextSize

Android 在运行时更改ListView中TextView的TextSize,android,textview,simplecursoradapter,text-size,Android,Textview,Simplecursoradapter,Text Size,我有一个列表视图,它使用一个自定义的SimpleCursorAdapter来显示信息。每个ListView行有三个TextView项 由于应用程序的性质,读者可能希望也可能不希望更改字体大小以便于阅读行项目上显示的文本 我想实现的是一种更新此TextView项的文本大小的方法,而无需从bindView()执行此操作 以下是我目前的做法: 第一步:通知适配器textSize应该更改 public void setAdjustTextSize(int size) { switc

我有一个
列表视图
,它使用一个自定义的
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和MDEScriptTextSizeres是自定义适配器的实例变量

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

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

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

2-事实上,由于一些代码是在
bindView
上运行的,因此现有视图不会立即看到更改,在滚动过程中的某个时刻,用户将有一些视图使用旧文本大小,一些视图使用新文本大小

话虽如此,我还是希望能够实现一些类似于重新初始化适配器的功能,但除了从头开始创建适配器之外,我不知道该怎么做我试着给NOTIFYDATASETCHANGE打电话,但没有效果


有什么想法吗?

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

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

您只需重写getView()方法,并在convertView不为null时重新使用它,或者在该行为null时为其膨胀一个新视图(并将其viewholder创建为标记)

然后,使用视图的viewHolder将TextView更新为新大小

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


为了更熟悉listView和适配器,请注意“.

显然不清楚我是否在使用自己的
SimpleCorsorAdapter
,@MarsAtomic和@android developer都建议我覆盖
getView()
,但是,当使用
SimpleCorsorAdapter
时,你不知道,您可以覆盖
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,我只在字体大小发生变化时重新创建适配器,我们都很高兴

发布自定义光标适配器。当我试图修改自定义列表适配器中视图的文本大小时,我会在适配器内部进行修改。
@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;       
}