0

我试图在我的应用程序中实现动态文本大小选项。出于某种原因,回收商只是在我的卡片视图中随机更改文本大小,而不是将所有文本设置为所需的大小。当我滚动列表时,顶部的卡片视图文本将正确更改,但接下来的 3-4 将保持默认并随机向下列表另一个卡片视图文本将正确显示。当我向上滚动列表时,正确显示的卡片视图将随机更改。

主要活动....

// Dark Mode Menu
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            mDrawer.openDrawer(GravityCompat.START);
            return true;
        case R.id.menu_night_mode_day:
            setNightMode(AppCompatDelegate.MODE_NIGHT_NO);
            break;
        case R.id.menu_night_mode_night:
            setNightMode(AppCompatDelegate.MODE_NIGHT_YES);
            break;
        case R.id.menu_night_mode_auto:
            setNightMode(AppCompatDelegate.MODE_NIGHT_AUTO);
            break;
        // Text Size Options
        case R.id.menu_text_size_small:
            setTextSize(18);
            break;
        case R.id.menu_text_size_medium:
            setTextSize(20);
            break;
        case R.id.menu_text_size_large:
            setTextSize(22);
            break;
    }
    return super.onOptionsItemSelected(item);
}

// Dark Mode Menu
private void setNightMode(@AppCompatDelegate.NightMode int nightMode) {
    AppCompatDelegate.setDefaultNightMode(nightMode);

    if (Build.VERSION.SDK_INT >= 11) {
        recreate();
    }
}

// Dynamic text size
private void setTextSize(int textSize) {
    TextView description = (TextView) findViewById(R.id.cardview_description);
    description.setTextSize(textSize);
    saveToPreferences(this, "THE_TEXT_SIZE", "" + textSize);
}

我的适配器....

public class MyPageAdapter extends Adapter<MyPageHolder> {

public List<MenuPageItems> datas;
private Activity activity;
public String dynamicTextSize;

public MyPageAdapter(Activity activity){
    datas = new ArrayList<>();
    this.activity = activity;
}

public void add(MenuPageItems dataModel){
    datas.add(dataModel);
}

public void add(MenuPageItems dataModel, int position){
    datas.add(position, dataModel);
}

public void addAll(List<MenuPageItems> menuPageItems){
    datas.addAll(menuPageItems);
}

@Override
public MyPageHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
    return createViewHolder(v, viewType);
}

@Override
public void onBindViewHolder(MyPageHolder holder, int position) {
    holder.bind(datas.get(position), activity, position);
    dynamicTextSize = "20";
}

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

@Override
public int getItemViewType(int position){
    return datas.get(position).getViewResId();
}

public int searchViewTypePosition(int viewType){
    int i = 0;
    boolean found = false;
    while(i < datas.size() && !found){
        if(datas.get(i).getViewResId() == viewType){
            found = true;
            i--;
        }
        i++;
    }
    return i;
}

public MyPageHolder createViewHolder(View v, int viewType){
    return datas.get(searchViewTypePosition(viewType)).createViewHolder(v, activity, this);
}
}

持有者....

public abstract class MyPageHolder extends RecyclerView.ViewHolder{

protected final Activity activity;
protected MyPageAdapter adapter;
public TextView txtTitle, txtDescription, txtTheContent;
public ImageView imgImage;
public View view;

public MyPageHolder(View v, Activity activity, MyPageAdapter adapter) {
    super(v);
    this.activity = activity;
    this.adapter = adapter;

    imgImage = (ImageView) v.findViewById(R.id.cardview_image);
    txtTitle = (TextView) v.findViewById(R.id.cardview_title);
    txtDescription = (TextView) v.findViewById(R.id.cardview_description);
    view = (CardView) v.findViewById(R.id.card_view);

    view.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            /*/ this is where the magic happens when clicked /*/
        }
    });
}

public void bind(MenuPageItems dataModel, Activity activity, final int position) {
    final MenuPageItems m = (MenuPageItems)dataModel;
    imgImage.setImageResource(m.image);
    txtTitle.setText(m.title);
    txtDescription.setText(m.description);
    //txtTheContent.setText(m.theContent);

    view.setOnClickListener(new View.OnClickListener() {
        @Override public void onClick(View v){

            Intent cvIntent = new Intent(view.getContext(), EndpageActivity.class);

            // header image to pass to endpage activity
            cvIntent.putExtra("endpageHeader", m.image);

            // text to pass to endpage activity
            cvIntent.putExtra("endpageTitle", m.title);
            cvIntent.putExtra("endpageTheContent", m.theContent);
            view.getContext().startActivity(cvIntent);
        }
    });
}
}

我是否需要向我的适配器或查看器添加一些内容以正确更新所有文本?

4

1 回答 1

0

我想我明白了,但我根本看不到你在哪里设置文本大小,你说它在一些卡片中随机变化。

在我看来,需要做的是在Holder的bind方法中设置大小。每次需要重新绘制卡片时都会执行此操作。您可以在 bind() 中读取共享首选项,但这非常低效,因为滚动时会多次调用持有者的绑定方法。你要避免在 Holders bind() 内做任何多余的工作

将 dynamicTextSize 成员变量添加到适配器并使用以下任一设置值:

  1. setText/getText向适配器添加大小,活动可以在需要时设置它。
  2. 在适配器的构造函数中检索文本大小,然后覆盖该notifyDataSetChanged()方法并在每次调用时再次提取该值。然后打电话super.notifyDataSetChanged()

例子:

@Override
public void notifyDataSetChanged() {
   this.dynamicTextSize = // Pull value from shared preferences
   super.notifiyDataSetChanged();
}

我也没有看到传递给持有者的 dynamicTextSize 值。由于 holder 有对适配器的引用,所以可以给适配器添加一个 getTextSize() 方法,然后 holder 可以调用适配器来获取它。

public MyPageHolder(View v, Activity activity, MyPageAdapter adapter) {
   ...
   this.dynamicTextSize = adapter.getTextSize()
}

最后,在 setTextSize() 方法中,您需要调用 adapter.notifyDataSetChanged() 来更新适配器。

更新 10/17

我试图在之前的帖子中添加一些细节。

主要活动

// Dynamic text size
private void setTextSize(int textSize) {

    //  Add a call to set the text to the adapter's member variable:
    mAdapter.setTextSize(textSize);

    // I'm not sure what description is here...  I don't see what type the member is
    description.setTextSize(textSize);
    saveToPreferences(this, "THE_TEXT_SIZE", "" + textSize);
}

在您的适配器中,添加一个方法来设置和获取文本大小。当文本大小发生变化时,主Activity会调用set,而每次需要设置TextView的大小时,都会由持有者调用get。

public class MyPageAdapter extends Adapter<MyPageHolder> {

    ...
    public String dynamicTextSize;

    public void setTextSize(int textSize) {
       dynamicTextSize = textSize;
    }
    // This will be called by the holder
    public int getTextSize() {
       return dynamicTextSize;
    } 
    ...
}

在您的持有人中:

public abstract class MyPageHolder extends RecyclerView.ViewHolder{
    public void bind(MenuPageItems dataModel, Activity activity, final int position) {
        ...

        // Call into the adapter to get the text size.
        int textSize = adapter.getTextSize();
        txtDescription.setTextSize(textSize);
    }
}

更新 10/19

我只需稍作改动就能让它工作。

  1. 在 MainActivity 中添加 getDynamicTextSize
  2. 从 MyPageAdapter 构造函数中添加对 get 的调用。

    public MyPageAdapter(Activity activity){
        datas = new ArrayList<>();
        this.activity = activity;
        dynamicTextSize = ((MainActivity)activity).getDynamicTextSize();
    }
    

虽然这确实有效,但它不会为您做一些事情。

  1. 将您的片段与始终作为 MainActivity 活动的子项联系起来,您可以通过界面解决此问题,但仍然不漂亮。

  2. 一旦用户选择了新的文本大小,就不会更新当前活动。由于 mainActivity 接受菜单事件,因此您需要通知任何 Fragment 处于活动状态,文本设置已更改,然后在适配器上调用 notifyDataSetChanged。

  3. 不设置自定义之外的文本大小RecyclerView。我看到您有一些不使用您的回收站视图的片段。这些不会采取设置。菜单中的设置会让您认为应用程序中的所有文本都应该更改。

这篇文章中接受的回复似乎是调整整个应用程序文本大小的好方法。您的应用程序中的一些更改几乎表明您已经看到了它。

于 2016-10-13T19:28:19.717 回答