0

アプリ内に動的テキスト サイズ オプションを実装しようとしています。何らかの理由で、リサイクラーは、すべてのテキストを目的のサイズに設定するのではなく、カードビュー内のテキスト サイズをランダムに変更するだけです。リストをスクロールすると、一番上の cardview テキストは正しく変更されますが、次の 3 ~ 4 はデフォルトのままで、リストの下にランダムに別の cardview テキストが正しく表示されます。リストを上にスクロールすると、正しく表示されるカードビューがランダムに変更されます。

主な活動....

// 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() 内で共有設定を読み取ることができますが、スクロール時に所有者の 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 値もわかりません。ホルダーにはアダプターへの参照があるため、 getTextSize() メソッドをアダプターに追加すると、ホルダーはアダプターを呼び出してそれを取得できます。

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);
}

アダプターで、テキスト サイズを設定および取得するメソッドを追加します。セットは、テキスト サイズが変更されたときにメイン アクティビティによって呼び出され、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 from の呼び出しを追加します。

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

これはうまくいきますが、うまくいかないことはほとんどありません。

  1. フラグメントを常に MainActivity アクティビティの子に結び付けます。インターフェイスを使用してこれを回避できますが、それでもきれいではありません。

  2. ユーザーが新しいテキスト サイズを選択しても、現在のアクティビティは更新されません。mainActivity はメニュー イベントを受け取るため、アクティブなフラグメントが何であれ、テキスト設定が変更されたことを通知し、アダプターで notifiyDataSetChanged を呼び出す必要があります。

  3. custom の外側のテキストのサイズを設定しませんRecyclerView。リサイクラー ビューを使用しないフラグメントがいくつかあるようです。これらは設定を取りません。メニューの設定では、アプリ内のすべてのテキストを変更する必要があると思われます。

この投稿で受け入れられた返信は、アプリ全体のテキスト サイズを調整する良い方法のようです。あなたのアプリのいくつかの変更は、あなたがそれを見たことをほとんど示しています。

于 2016-10-13T19:28:19.717 に答える