0

我有一个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,现有视图不会立即看到更改,并且在滚动过程中的某个时刻,用户将有一些旧文本大小的视图,而一些新文本尺寸。附上示例图片。

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

有任何想法吗?

4

3 回答 3

0

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

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

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

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

为了更熟悉 listView 和适配器,请观看“ listView 的世界”。

于 2013-05-07T22:55:52.437 回答
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;
}
于 2013-05-07T22:49:34.507 回答
0

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

我最终要做的,这是我想要避免的,只是从头开始重新创建适配器,并在onNewView(). 我对结果非常满意,因为这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,我只在字体大小发生变化时重新创建适配器,我们都很高兴。

于 2013-05-07T23:10:25.320 回答