Listview片段正在按下后退按钮创建

时间:2014-03-23 10:13:23

标签: android listview android-fragments android-listview adapter

我正在我的ListView片段中使用加载器,并且在按下“后退”按钮时重新创建它。你能告诉我如何处理这个事件吗?

这是我的ListView片段代码。这里我有一个布尔变量,我在点击列表项时设置为true。但是一旦按下后退按钮,onCreateView将被调用,因此后退按钮将为假。

public class GTFragment  extends SherlockFragment implements LoaderCallbacks<Cursor>{

    ListView mTListview = null;
    GoogleTasksAdapter mGTasksAdapter = null;
    private SQLiteCursorLoader mTLoader=null;
    private LoaderManager mTLoaderManager;
    private String mSelectedListID = null; 
    private boolean mIsBackbuttonisPressed = false;

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.task_home_activity, container, false);


    if(!mIsBackbuttonisPressed)
        getLoaderManager().initLoader(0, null, this);

     mTListview   = (ListView) view.findViewById(R.id.id_task_list_home_activity);

     mGTasksAdapter = new GoogleTasksAdapter(getActivity());

     mTListview.setOnItemClickListener(new OnItemClickListener() {

         @Override
         public void onItemClick(AdapterView<?> listview,
            View clickedview, int position, long arg3) {
            // TODO Auto-generated method stub

            GoogleTaskItem item = new GoogleTaskItem();

            Cursor coursor = ((GoogleTasksAdapter)listview.getAdapter()).getCursor();



            if(coursor.moveToPosition(position))
            {


                mIsBackbuttonisPressed = true;
                GoogleTaskController.get_googletask_controllerObj()
                  .LaunchTaskPreviewActivity();                 
            }

        }

    });

   mTListview.setAdapter(mGTasksAdapter);  
   mIsBackbuttonisPressed = false;

   return view;

  }

我的片段活动类代码

public class TLActivity extends SherlockFragmentActivity {

    LeftSliderTaskListOptions mTaskOptionsFragment = null;
    GoogleTasksFragment mTFragment = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);



        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);

        setContentView(R.layout.layout_gt_list);


//      FragmentTransaction tfragment = this.getSupportFragmentManager().beginTransaction();
        mTFragment = new GTasksFragment();
        t.replace(R.id.id_tfragment, mTFragment);
        t.commit();


    }

2 个答案:

答案 0 :(得分:1)

我不认为接受的答案是正确的,因为Fragment.onSaveInstanceState在托管它的活动需要保存其状态之前不会被调用:docs状态:

  

在很多情况下,碎片可能会被拆除   (例如当放置在没有UI显示的后台堆栈上时),但是它   在其拥有的活动实际需要之前,国家不会被保存   保存它的状态。

换句话说:如果您为每个屏幕使用具有多个片段的活动(这是非常常见的),则移动下一个屏幕时将不会保存片段状态。

你也不能使用Fragment.setRetainInstance,因为他只是指那些不在后台的片段。

大多数时候,你不必考虑这个问题,但有时这很重要。就像滚动列表并想要“记住”滚动位置一样。

我花了很长时间才意识到放在后台堆栈上的片段有点保存,您可以重复使用已经创建的视图,而不是每次片段调用onCreateView时都创建一个。我的设置是这样的:

public abstract class BaseFragment extends Fragment {
     private boolean mSaveView = false;
     private SoftReference<View> mViewReference;

     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
          if (mSaveView) {
               if (mViewReference != null) {
                    final View savedView = mViewReference.get();
                    if (savedView != null) {
                         if (savedView.getParent() != null) {
                              ((ViewGroup) savedView.getParent()).removeView(savedView);
                              return savedView;
                         }
                    }
               }
          }

          final View view = inflater.inflate(getFragmentResource(), container, false);
          mViewReference = new SoftReference<View>(view);
          return view;
     }

     protected void setSaveView(boolean value) {
           mSaveView = value;
     }
}

public class MyFragment extends BaseFragment {
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
          setSaveView(true);
          final View view = super.onCreateView(inflater, container, savedInstanceState);
          ListView placesList = (ListView) view.findViewById(R.id.places_list);
          if (placesList.getAdapter() == null) { // this check is important so you don't restart your adapter
               placesList.setAdapter(createAdapter());
          }
     }
}

答案 1 :(得分:0)

您有多种方法可以解决此问题。

  1. 像这样覆盖onSaveInstanceState:

    @Override
    public void onSaveInstanceState (Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean("mIsBackbuttonisPressed", mIsBackbuttonisPressed);
    }
    

    然后在您的onCreateView中,您可以通过以下方式获取变量:

    if (savedInstanceState != null)
        mIsBackbuttonisPressed = savedInstanceState.getBoolean("mIsBackbuttonisPressed", false);
    
  2. 您可以在片段的onCreate方法中设置this.setRetainInstance(true);

  3. 如果您可以发布您的活动代码并创建您的片段,我也可以告诉您其他选项。 (P.S我不能把它写成评论,所以在答案中张贴。)