搜尋此網誌

顯示具有 Fragment 標籤的文章。 顯示所有文章
顯示具有 Fragment 標籤的文章。 顯示所有文章

2015年9月20日 星期日

【Android】java.lang.IllegalStateException: Fragment not attached to Activity

ref:
http://stackoverflow.com/a/22544283

Generally you get that error when you try to perform work after the Fragment is no longer attached to the Activity. In the callback that triggers the IllegalStateException add a check for isAdded:http://developer.android.com/reference/android/app/Fragment.html#isAdded()
if(!isAdded()) {
    return;
}
http://stackoverflow.com/a/10941410
I've found the very simple answer: isAdded():
Return true if the fragment is currently added to its activity.
@Override
protected void onPostExecute(Void result){
    if(isAdded()){
        getResources().getString(R.string.app_name);
    }
}
To avoid onPostExecute from being called when the Fragment is not attached to the Activity is to cancel the AsyncTask when pausing or stopping the Fragment. Then isAdded() would not be necessary anymore.

【Android】移除FragmentManager裡的BackStack entry

ref:
Is this the right way to clean-up Fragment back stack when leaving a deeply nested stack?
http://shareandopen.tumblr.com/post/35328568659/android-clear-all-back-stack

為了好的使用者體驗,希望在程式運作到某一個情境時,清除所有的back stack entry,讓使用者不要在按下back按鍵時,發生一些悲劇體驗的話,可以利用程式碼來清除back stack entry。

// In your FragmentActivity use getSupprotFragmentManager() to get the FragmentManager.

// Clear all back stack.
int backStackCount = getSupportFragmentManager().getBackStackEntryCount();
for (int i = 0; i < backStackCount; i++) {

    // Get the back stack fragment id.
    int backStackId = getSupportFragmentManager().getBackStackEntryAt(i).getId();

    fm.popBackStack(backStackId, FragmentManager.POP_BACK_STACK_INCLUSIVE);

} /* end of for */

2015年9月19日 星期六

【Android】how to open a different fragment on recyclerview OnClick

ref:
http://stackoverflow.com/a/30434250

So simplified version, here's my onbindVH:
 @Override
    public void onBindViewHolder(FeedsViewHolder holder, int position) {
        final Feed item = mFeeds.get(position);

        holder.textView1.setText(item.getText());
        holder.imageView.setImageDrawable(mContext.getResources().getDrawable(item.getImage));
        holder.imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                fragmentJump(item);
            }
        });
    }
here's fragmentJump:
private void fragmentJump(Feed mItemSelected) {
    mFragment = new Fragment2();
    mBundle = new Bundle();
    mBundle.putParcelable("item_selected_key", mItemSelected);
    mFragment.setArguments(mBundle);
    switchContent(R.id.frag1, mFragment);
}
here's switchContent on the adapter:
public void switchContent(int id, Fragment fragment) {
    if (mContext == null)
        return;
    if (mContext instanceof MainActivity) {
        MainActivity mainActivity = (MainActivity) mContext;
        Fragment frag = fragment;
        mainActivity.switchContent(id, frag);
    }

}
and lastly, here's the switchContent on MainActivity:
public void switchContent(int id, Fragment fragment) {
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.replace(id, fragment, fragment.toString());
    ft.addToBackStack(null);
    ft.commit();
}
I know it can still be simplified, but it works as is. I hope it helps. :)

2015年9月1日 星期二

【Android】Different Fragments using different / common menu in Action Bar

ref:
http://stackoverflow.com/a/30556508
http://stackoverflow.com/a/18714611
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1120/2025.html

今天想要在不同的fragment使用特定的menu item,但有些menu item是可以共用。

1.建立一個通用menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      xmlns:tools="http://schemas.android.com/tools"
      tools:context=".MainActivity">
    <group
        android:id="@+id/main_menu_group">
        <item
            android:id="@+id/action_refresh"
            android:icon="@drawable/ic_refresh"
            android:orderInCategory="90"
            android:title="@string/action_refresh"
            app:showAsAction="ifRoom"/>

        <item
            android:id="@+id/action_settings"
            android:orderInCategory="100"
            android:title="@string/action_settings"
            app:showAsAction="never"/>
    </group>
</menu>

先把需要通用的menu item寫在<group>外,至於範例是想製造每個fragment呈現不同的menu item。

2.建立特定的menu - menu_f1.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_search"
        android:icon="@drawable/ic_search"
        android:imeOptions="actionSearch"
        android:inputType="textCapWords"
        android:orderInCategory="80"
        android:title="search"
        app:actionViewClass="android.support.v7.widget.SearchView"
        app:showAsAction="ifRoom|collapseActionView"/>
</menu>

3.在需要擁有特定menu item的fragment的onCreateView
增加setHasOptionsMenu(true);
來告知這個fragment有另外的OptionsMenu(參考)

4.建立onCreateOptionsMenu(Menu menu, MenuInflater inflater) method,並在onCreateOptionsMenu  引用(inflate)特定的menu,並把通用的menu item顯示設為false。如下所示:
@Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        // Inflate the menu; this adds items to the action bar if it is present.
        inflater.inflate(R.menu.menu_air, menu);

        menu.setGroupVisible(R.id.main_menu_group, false);
//        menu.findItem(R.id.action_settings).setVisible(false);
//        menu.findItem(R.id.action_refresh).setVisible(false);
        
        super.onCreateOptionsMenu(menu, inflater);

    }


  • 透過1.設定group的方式,將group內的menu item設為不顯示。
  • 或者是用menu.findItem(R....).setVisible(false);將個別menu item設為不顯示。