8

を発見期待示す更新しないI ViewPagerタブ+ ViewPagerはなく奇妙な警告状態3が2

私は3つのタブを追加したとTabLayoutを含むmainactivityを有し、各タブはrecyclerviewを含有する別の断片を有し、これらのリサイクルビューには、ビューページをスワイプするたびにチェックボックスが更新/更新される必要があります(チェックされた位置を共有設定で保存し、共有設定で更新)。

ここでの問題は、タブ1のチェックボックスをオンにするたびに、タブ2が更新/更新されずにリサイクルビューがスクロールダウンされるまでです。 tab3は正常に動作しています。logcatでも奇妙な警告が表示されています。

03-05 09:35:53.345 4317-4327/com.example.rubin W/art: Suspending all threads took: 6.805ms 
    03-05 09:35:58.310 4317-4317/com.example.rubin W/FragmentManager: moveToState: Fragment state for Tab3{10a5f1f0 #2 id=0x7f0d00b6} not updated inline; expected state 3 found 2 
    03-05 09:36:01.363 4317-4317/com.example.rubin W/FragmentManager: moveToState: Fragment state for Tab1{2d9aa887 #1 id=0x7f0d00b6} not updated inline; expected state 3 found 2 

各断片のための私のPagerAdapter

public class PagerAdapter1 extends FragmentStatePagerAdapter { 
    int mNumOfTabs; 
    public PagerAdapter1(FragmentManager fm, int NumOfTabs) { 
     super(fm); 
     this.mNumOfTabs = NumOfTabs; 
    } 
    @Override 
    public Fragment getItem(int position) { 
     switch (position) { 
      case 0: 
       return new Tab1(); 
      case 1: 
       return new Tab2(); 
      case 2: 
       return new Tab3(); 

      default: 
       return null; 

     } 
    } 

    @Override 
    public int getCount() { 
     return mNumOfTabs; 
    } 
} 

Tablayout OnPageChangelistener

final PagerAdapter1 adapter = new PagerAdapter1 
       (getSupportFragmentManager(), tabLayout1.getTabCount(), getApplicationContext()); 
     viewPager1.setAdapter(adapter); 
     viewPager1.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout1)); 
     tabLayout1.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { 
      @Override 
      public void onTabSelected(TabLayout.Tab tab) { 
       viewPager1.setCurrentItem(tab.getPosition()); 
       adapter.notifyDataSetChanged(); 
      } 

      @Override 
      public void onTabUnselected(TabLayout.Tab tab) { 

      } 

      @Override 
      public void onTabReselected(TabLayout.Tab tab) { 
      } 
     }); 
    } 

コード。このフラグメントの状態を変化させる活性断片の近傍に

public class Tab1 extends Fragment { 

     @Override 
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
      View v = inflater.inflate(R.layout.home_tab1_recycler, container, false); 
      RecyclerView rv = (RecyclerView) v.findViewById(R.id.home_recyclerview); 
      LinearLayoutManager llm = new LinearLayoutManager(getContext()); 
      rv.setLayoutManager(llm); 
      rv.setHasFixedSize(true); // to improve performance 
      rv.setAdapter(new HomeManager()); // the projectdatabase manager is assigner to the RV 
      return v; 
     } 

     public class HomeManager extends RecyclerView.Adapter<HomeManager.RecyclerViewHolder> { 
    int Length,h; 
View v1; 
     ArrayList<String> PROJECT_ID = new ArrayList<String>(); 
Set<String> set; 
     List<String> selected; 
    public class RecyclerViewHolder extends RecyclerView.ViewHolder { 
    CheckBox mCheck; 
     RecyclerViewHolder(final View itemView) { 
        super(itemView); 
     mCheck = (CheckBox) itemView.findViewById(R.id.PROJECT_fav); 
    SharedPreferences pref = getContext().getSharedPreferences("MirSP", Context.MODE_PRIVATE); 
        set = pref.getStringSet("FAV", null); 
     if (set != null) { 
         selected = new ArrayList<String>(set); 
        } else { 
         selected = new ArrayList<String>(); 
        } 
    mCheck.setOnClickListener(new View.OnClickListener() { 
         @Override 
         public void onClick(View v) { 
    h = getAdapterPosition(); 
    check = PROJECT_ID.get(h); // for saving the project id from json. 
    if (selected.contains(check)) { 
            selected.remove(check); 
            mCheck.setBackgroundResource(R.drawable.ic_favorite_white1_24dp); 
            Snackbar snackbar = Snackbar.make(v, "Property Unfavorited", Snackbar.LENGTH_SHORT); 
            snackbar.show(); 
           } else { 
            selected.add(check); 
            mCheck.setBackgroundResource(R.drawable.ic_favorite_white_24dp); 
            Snackbar snackbar = Snackbar.make(v, "Property Favorited", Snackbar.LENGTH_SHORT); 
            snackbar.show(); 

           } 
           Log.e("HF update checked", String.valueOf(selected)); 
           Set<String> set = new HashSet<String>(); 
           set.addAll(selected); 
           SharedPreferences pref = getContext().getSharedPreferences("MirSP", Context.MODE_PRIVATE); 
           SharedPreferences.Editor editor = pref.edit(); 
           editor.putStringSet("FAV", set); 
           editor.commit(); 
          } 
     } 
        }); 
    @Override 
      public RecyclerViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { 
       v1 = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recyclerview_item, viewGroup, false); 
       return new RecyclerViewHolder(v1); 
      } 

      @Override 
      public void onBindViewHolder(final RecyclerViewHolder viewHolder, int i) { 
    SharedPreferences pref = getContext().getSharedPreferences("MirSP", Context.MODE_PRIVATE); 
       set = pref.getStringSet("FAV", null); 
       if (set != null) { 
        selected = new ArrayList<String>(set); 
       } else { 
        selected = new ArrayList<String>(); 
       } 
       Log.e("HF update UI", String.valueOf(selected)); 
    if (String.valueOf(selected).contains(String.valueOf(PROJECT_ID.get(i)))) { 
         viewHolder.mCheck.setBackgroundResource(R.drawable.ic_favorite_white_24dp); 
        } else { 
         viewHolder.mCheck.setBackgroundResource(R.drawable.ic_favorite_white1_24dp); 
        } 
       } 
    @Override 
      public int getItemCount() { 
       //Code for Total length of json 
       return Length; 
      } 
+1

したがって、タブ1の何かをチェックすると、タブ2が更新されるはずですか? –

+0

はい。タブ2とタブ3で更新する必要がありますが、タブ2は、下にスクロールして、タブ3が正常に動作している場合にのみ更新されます。 –

+2

タブ2に行くと、タブ3を更新している何か(おそらく 'adapter.notifyDataSetChanged();')が呼び出されている可能性があります。 –

答えて

4

FragmentPagerAdapterコールsetUserVisibleHint(true|false)。 これは少なくとも「奇妙な警告メッセージ」の回答ですが、問題が解決しないことがあります。 - しかし、私はまだでています

public abstract class AbstractTabPagerAdapter extends PagerAdapter { 

    private static final String TAG = AbstractTabPagerAdapter.class.getCanonicalName(); 

    private final FragmentManager mFragmentManager; 

    private FragmentTransaction mCurTransaction; 

    private Fragment mCurrentPrimaryItem = null; 

    public AbstractTabPagerAdapter(FragmentManager fragmentManager) { 
     mFragmentManager = fragmentManager; 
    } 

    @Override 
    public Object instantiateItem(ViewGroup container, int position) { 
     if (mCurTransaction == null) { 
      throw new IllegalArgumentException("current transaction must not be null"); 
     } 
     String fragmentTag = makeFragmentName(container.getId(), position); 
     Fragment fragment = (Fragment) mFragmentManager.findFragmentByTag(fragmentTag); 
     if (fragment != null) { 
      mCurTransaction.attach(fragment); 
      Log.d(TAG, "Attaching existing fragment " + fragment + " at position " + position); 
      //mCurTransaction.add(container.getId(), fragment, makeFragmentName(container.getId(), position)); 
     } else { 
      fragment = getItem(position); 
      mCurTransaction.add(container.getId(), fragment, fragmentTag); 
      Log.d(TAG, "Attaching new fragment " + fragment + " at position " + position); 
     } 

     if (fragment != mCurrentPrimaryItem) { 
      fragment.setMenuVisibility(false); 
      //fragment.setUserVisibleHint(false); 
     } 

     return fragment; 
    } 

    @Override 
    public void destroyItem(ViewGroup container, int position, Object object) { 
     if (mCurTransaction == null) { 
      throw new IllegalArgumentException("current transaction must not be null"); 
     } 
     mCurTransaction.detach((Fragment) object); 
     //mCurTransaction.remove((Fragment)object); 
    } 

    @Override 
    public void setPrimaryItem(ViewGroup container, int position, Object object) { 
     //super.setPrimaryItem(container, position, object); 
     Fragment fragment = (Fragment) object; 
     if (fragment != mCurrentPrimaryItem) { 
      Log.d(TAG, "set Primary item " + position + " to " + fragment); 
      if (mCurrentPrimaryItem != null) { 
       mCurrentPrimaryItem.setMenuVisibility(false); 
       // this command unexpectedly changes the state of the fragment which leads to a warning message and possible some strange behaviour 
       //mCurrentPrimaryItem.setUserVisibleHint(false); 
      } 
      if (fragment != null) { 
       fragment.setMenuVisibility(true); 
       //fragment.setUserVisibleHint(true); 
      } 
      mCurrentPrimaryItem = fragment; 
     } 
    } 

    @Override 
    public boolean isViewFromObject(View view, Object fragment) { 
     return ((Fragment) fragment).getView() == view; 
    } 

    public abstract Fragment getItem(int position); 

    @Override 
    public void startUpdate(ViewGroup container) { 
     super.startUpdate(container); 
     if (mCurTransaction != null) { 
      throw new IllegalArgumentException("current transaction must not be null"); 
     } 
     mCurTransaction = mFragmentManager.beginTransaction(); 
     Log.d(TAG, "FragmentTransaction started"); 
    } 

    @Override 
    public void finishUpdate(ViewGroup container) { 
     if (mCurTransaction != null) { 
      mCurTransaction.commit(); 
      mCurTransaction = null; 
      //mFragmentManager.executePendingTransactions(); 
      Log.d(TAG, "FragmentTransaction committed"); 
     } else { 
      throw new IllegalArgumentException("current transaction must not be null"); 
     } 
    } 

    private String makeFragmentName(int viewId, int position) { 
     if (viewId <= 0) 
      throw new IllegalArgumentException("viewId " + viewId); 
     return "tabpageradptr:" + getPageTitle(position) + ":" + viewId + ":" + position; 
    } 

} 

警告メッセージが今なくなっており、現在、私は任意の欠陥を経験しない次のように私は自分のFragmentPagerAdapterを作成したという警告メッセージを解決する方法についてのあなたのコメントについて

研究の途中です。

+0

はい。どうすればこの問題を克服できますか? –

+1

警告メッセージを克服する方法の追加例。 – mikes

+0

ありがとうございました。 –

2

重要ではありません。それは単なる警告です。 ViewPagerレイアウトの背景をnullに変更してください(背景を設定しないでください)。

+6

あなたが提供するソリューションを詳細に教えてください。 – abarisone

+0

ohkどこに問題がありますか? –

2

私はこの問題に多くの時間を費やしました。問題は、それがラインに更新されませ

を警告スローしますOnPageChangeListenerリスナーでviewpagerを更新しようとしている

ソリューション:

すべてのデータの変更や更新ビューは、OnPageChangeListenerの外に を呼び出す必要があります例:フラグメントのonCreateView

私の警告は消えました!そしてviewpager update completelly

+1

私は完全にそれを理解していない、あなたは私に例を示すことができますか? –

+0

@Ruben onTabSelected、 'viewPager1.setCurrentItem(tab.getPosition());'を呼び出すだけです。 only、notifydatasetこのメソッドの変更は間違っています。警告と断片化はインラインで更新されません。 – cuasodayleo

+0

警告については気にしませんが、中間のタブは正しく更新されません。それでも古い結果が表示されます。 –

2

私はFragmentPagerAdapterを使用して最良の方法を考え出しましたが、その警告をなくすわけではありませんが、目的を解決することは誰でも私にその警告が実際に何を伝えるのか、それは私の最高の関心事です。

最初に、次のようにビューページ作成メソッドで使用されるすべてのフラグメントで使用されます。

 
public void updateView() { 
    //Update whatever views or data you want to update 
} 

また断片がユーザに見えるかどう通知するFragmentPagerAdapterに使用されるメソッドをオーバーライドsetUserVisibleHint。

 
@Override 
    public void setUserVisibleHint(boolean isVisibleToUser) { 
     this.isVisibleToUser = isVisibleToUser; 
     super.setUserVisibleHint(isVisibleToUser); 
    } 

最後にフラグメントに次のコードを追加して、フラグメントが表示されているときにビュー/日付を更新します。

 
@Override 
    public void onStart() { 
      if (isVisibleToUser) 
       updateView(); 
    } 

その後、あなたのTabFragmentまたはアクティビティでこれを実装する

 
viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 
      @Override 
      public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 

      } 

      @Override 
      public void onPageSelected(int position) { 

       switch (position) { 
        case 0: { 
         ((Fragment) mFragmentList.get(0)).updateView(); 
         break; 
        } 
        case 1: { 
         ((Fragment) mFragmentList.get(1)).updateView(); 
         break; 
        } 
       } 
      } 

このいずれかで、あなたがスワイプや誰もが任意の問題やバグを見つけた場合は、タブをクリックし、データconsistantly更新の世話をします私にこのソリューションを適用するアプローチを与えた上記の解決策に投票しました。ありがとう@mikes

1

"W/FragmentManager: moveToState: … expected state 3 found 2"警告は無視することができ、サポートライブラリv24.0.0では削除されました。公式の開発者answerから

引用:あなたは追加の何もする必要はありません

。これは通知ログメッセージのみです。 [...]

ここで説明するログ自体は動作に影響しません。他の問題がある場合は 新しいバグを開いてください。他の問題を融合させる同じバグで を実行すると、別々の問題を追跡するのがより困難になります。

ログの問題としてコメントを閉じることは、将来の リリースで解決されました。

2

ビューでは、ページャの隣接するタブが同時に読み込まれます。したがって、タブ1のあなたの行動は、既にロードされているので、タブ2に反映されません。この問題を解決するには、ブロードキャスト受信機を使用する必要があります。タブ1でイベントをブロードキャストし、タブ2でイベントを受信する