Viewpager当我导航回来时,我得到的是一个空白页面

时间:2015-01-15 12:48:24

标签: java android

我在HomeActivity(extends FragmentActivity)和2个标签和4个ListFragments中托管了一个Viewpager,我设法从一个位置(同一个标签)从ListFragment导航到另一个,我的问题是当我向后导航使用(onBackPressed())最近的ListFragment被删除了,它没有被第一个ListFragment取代,这就是为什么我得到一个空白页面,我似乎并没有对我的代码做错了。

以下是一些图片(连续订购)以清除我的解释(我不能直截了当,因为我没有足够的声誉):

通过单击第一个ListFragment,我进入第二个ListFragment。

当我回来时,我得到一个空白页面 http://i.stack.imgur.com/RxJhA.jpg

以下是一些代码:

public class HomeActivity extends FragmentActivity
    implements ActionBar.TabListener 
    {
    private ViewPager viewPager;
    private TabsPagerAdapter mAdapter;
    private ActionBar actionBar;
    // Tab titles
    private String[] tabs = { "WORKOUTS", "PROGRAMS" };

    // create DBHelper objects for workout and program database
    public static DBHelperWorkouts dbWorkouts;
    public static DBHelperPrograms dbPrograms;

    // create objects of fragments
    WorkoutsFragment workoutsFrag = new WorkoutsFragment();
    WorkoutListFragment workoutListFrag;

    ProgramsFragment programsFrag = new ProgramsFragment();
    public static ProgramListFragment programListFrag;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);

        // Initilization
                viewPager = (ViewPager) findViewById(R.id.pager);
                actionBar = getActionBar();
                mAdapter = new TabsPagerAdapter(getSupportFragmentManager());

                viewPager.setAdapter(mAdapter);
                //actionBar.setHomeButtonEnabled(false);
                actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);        

                // Adding Tabs
                for (String tab_name : tabs) {
                    actionBar.addTab(actionBar.newTab().setText(tab_name)
                            .setTabListener(this));
                }


                /**
                 * on swiping the viewpager make respective tab selected
                 * */
                viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

                    @Override
                    public void onPageSelected(int position) {
                        // on changing the page
                        // make respected tab selected
                        actionBar.setSelectedNavigationItem(position);
                    }

                    @Override
                    public void onPageScrolled(int arg0, float arg1, int arg2) {
                    }

                    @Override
                    public void onPageScrollStateChanged(int arg0) {
                    }
                });

        dbWorkouts = new DBHelperWorkouts(this);
        dbPrograms = new DBHelperPrograms(this);

        /**
         * when this app's installed at the first time, code below will
         * copy database stored in assets to
         * /data/data/com.daily.workout.app/databases/
         */
        try {
            dbWorkouts.createDataBase();
        }catch(IOException ioe){
            throw new Error("Unable to create database");
        }

        // then, the database will be open to use
        try{
            dbWorkouts.openDataBase();
        }catch(SQLException sqle){
            throw sqle;
        }

        /**
         * when this app's installed at the first time, code below will
         * copy database stored in assets to
         * /data/data/com.daily.workout.app/databases/
         */
        try {
            dbPrograms.createDataBase();
        }catch(IOException ioe){
            throw new Error("Unable to create database");
        }

        // then, the database will be open to use
        try{
            dbPrograms.openDataBase();
        }catch(SQLException sqle){
            throw sqle;
        }



    }



    @Override
    public void onTabSelected(Tab tab, android.app.FragmentTransaction ft) {
        // TODO Auto-generated method stub
        // on tab selected
                // show respected fragment view
                viewPager.setCurrentItem(tab.getPosition());

    }

    @Override
    public void onTabUnselected(Tab tab, android.app.FragmentTransaction ft) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onTabReselected(Tab tab, android.app.FragmentTransaction ft) {
        // TODO Auto-generated method stub

    }





    // close database before app destroy
    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        dbWorkouts.close();
        dbPrograms.close();
        super.onDestroy();
    }




    /**
     * Identifies whether the back is called form a child fragment or a parent fragment
     * and takes necessary steps then.
     */
    @Override
    public void onBackPressed() {
        // TODO Auto-generated method stub
        //super.onBackPressed();

        ListFragment fragmentList = (ListFragment) this.getSupportFragmentManager().
                findFragmentByTag("android:switcher:" + R.id.pager + ":" + viewPager.getCurrentItem());
                //Toast.makeText(this, " "+viewPager.getCurrentItem(), Toast.LENGTH_SHORT).show();
                if (fragmentList != null && fragmentList instanceof BaseFragment) // could be null if not instantiated yet
                { 
                    if (fragmentList.getView() != null) {
                        BaseFragment bf = (BaseFragment)fragmentList;
                        if(bf.isShowingChild()) {
                            //WorkoutsFragment.mCallback1.onSwitchToNextFragment(0);
                            replaceChild(bf, viewPager.getCurrentItem());
                        }
                        else {
                            backButton();
                        }
                    }
                }
    }


    // Back Button Pressed
        private void backButton() {
            finish();
        }

        public void replaceChild(BaseFragment oldFrg, int position) {
            mAdapter.replaceChildFragment(oldFrg, position);
        }

}

FragmentPagerAdapter

Public class TabsPagerAdapter extends FragmentPagerAdapter
  {
    //implements WorkoutsFragment.WorkoutsFragmentListener

        private final FragmentManager mFragmentManager;
        private BaseFragment mFragmentAtPos0;

    public TabsPagerAdapter(FragmentManager fm) {
        super(fm);
        mFragmentManager = fm;  
    }


    @Override
    public Fragment getItem(int index) {

      if(index==0)
      {

            if (mFragmentAtPos0 == null)
            {
                mFragmentAtPos0 = WorkoutsFragment.newInstance(new WorkoutsFragmentListener()
                {
                    @Override
                    public void onSwitchToNextFragment(int pos) {
                        // TODO Auto-generated method stub
                        Log.d("onSwitchToNextFragmen", "dkhel1");
                        Bundle bundle = new Bundle();
                        bundle.putInt("selectedID", pos);
                        WorkoutListFragment w = WorkoutListFragment.newInstance();
                        w.setArguments(bundle);


                        mFragmentManager.beginTransaction().remove(mFragmentAtPos0).commit();
                        mFragmentAtPos0 =  w;
                        mFragmentAtPos0.setShowingChild(true);

                        notifyDataSetChanged(); 

                    }

                });

            }

            return mFragmentAtPos0;

      }
      else{

            return new ProgramsFragment();

        }

        //return null;
    }

    @Override
    public int getCount() {
        // get item count - equal to number of tabs
        return 2;
    }

    @Override
    public int getItemPosition(Object object)
    {
        if (object instanceof WorkoutsFragment && mFragmentAtPos0 instanceof WorkoutListFragment)
            return POSITION_NONE;
        return POSITION_UNCHANGED;
    }



    public void replaceChildFragment(BaseFragment oldFrg, int position) {
        switch (position) {
        case 0:

            mFragmentManager.beginTransaction().remove(oldFrg).commit();

                mFragmentAtPos0 = WorkoutsFragment.newInstance(new WorkoutsFragmentListener()
             {
                    @Override
                    public void onSwitchToNextFragment(int pos) {
                        // TODO Auto-generated method stub

                    mFragmentManager.beginTransaction().remove(mFragmentAtPos0).commit();
                    WorkoutListFragment w = WorkoutListFragment.newInstance();
                     mFragmentAtPos0 =  w;
                     mFragmentAtPos0.setShowingChild(true);
                     notifyDataSetChanged();

                    }
             });

           notifyDataSetChanged();
            break;

//      case 1: second ListFragment i'll do it later 

//          break;                  

        default:
            break;
        }
    }




}

First ListFragment

public class WorkoutsFragment extends BaseFragment {
     //OnCategorySelectedListener mCallback;
    public static WorkoutsFragmentListener mCallback1;

    // create object of listview
    ListView list;


    // create object of custom adapter
    WorkoutsAdapter wa;

    // create arraylist variables to store data
    static ArrayList<Integer> WorkoutID = new ArrayList<Integer>();
    static ArrayList<String> Category_name = new ArrayList<String>();
    static ArrayList<String> Category_image = new ArrayList<String>();
    static ArrayList<String> Total = new ArrayList<String>();

    // create arraylist variable to store object data from database
    ArrayList<ArrayList<Object>> data;


     public interface WorkoutsFragmentListener
        {
            void onSwitchToNextFragment(int p);
        }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        View v = inflater.inflate(R.layout.fragment_list, container, false);

        // connect object of listview and listview id on xml
        list = (ListView) v.findViewById(android.R.id.list);


        wa = new WorkoutsAdapter(getActivity());

        // call asynctask class to get data from database
        new getCategoryList().execute();

        return v;
    }


    @Override
        public void onListItemClick(ListView l, View v, int position, long id) {
            // TODO Auto-generated method stub
            super.onListItemClick(l, v, position, id);




            mCallback1.onSwitchToNextFragment(WorkoutID.get(position));


                // Set the item as checked to be highlighted when in two-pane layout
               list.setItemChecked(position, true);
        }

     public static WorkoutsFragment newInstance(WorkoutsFragmentListener work) {
         mCallback1 = work;
         WorkoutsFragment w = new WorkoutsFragment();
         return w;
     }


    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception.
        try {
        //   mCallback = (WorkoutsFragmentListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnHeadlineSelectedListener");
        }
    }

    // asynctask class that is used to fetch data from database in background
    public class getCategoryList extends AsyncTask<Void, Void, Void>{

        ProgressDialog progress;

        @Override
         protected void onPreExecute() {
          // TODO Auto-generated method stub
            // show progress dialog when fetching data from database
            progress= ProgressDialog.show(
                    getActivity(), 
                    "", 
                    getString(R.string.loading_data), 
                    true);
        }

        @Override
        protected Void doInBackground(Void... params) {
            // TODO Auto-generated method stub
            getDataFromDatabase();
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            // TODO Auto-generated method stub
            // when finishing fetching data, close progress dialog and show data on listview
            // if available, otherwise show toast message
            progress.dismiss();
            if(WorkoutID.size() != 0){
                setListAdapter(wa);
                //list.setAdapter(wa);
            }else{
                Toast.makeText(getActivity(), getString(R.string.no_data_workout), Toast.LENGTH_SHORT).show();
            }
        }
    }

    // method to create arraylist variables before used
    void clearData(){
        WorkoutID.clear();
        Category_name.clear();
        Category_image.clear();
        Total.clear();
    }

    // method to fetch data from database
    public void getDataFromDatabase(){
        data = HomeActivity.dbWorkouts.getAllCategories();

        clearData();

        for(int i=0;i<data.size();i++){
            ArrayList<Object> row = data.get(i);

            WorkoutID.add(Integer.parseInt(row.get(0).toString()));
            Category_name.add(row.get(1).toString());
            Category_image.add(row.get(2).toString());
            Total.add(row.get(3).toString());
        }
    }


    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();

    }
}

Second ListFragment

public class WorkoutListFragment extends BaseFragment {


    // create object of listview
    ListView list;


    // create object of custom adapter class
    WorkoutListAdapter wla;

    // create arraylist variable to store object data from database
    ArrayList<ArrayList<Object>> data;

    // create variables to store selected value
    int SelectedID, SelectedDayID = 0, SelectedPosition;

    // create arraylist variables to store data from database
    static ArrayList<Integer> WorkoutID = new ArrayList<Integer>();
    static ArrayList<String> Name = new ArrayList<String>();
    static ArrayList<String> Image = new ArrayList<String>();
    static ArrayList<String> Time = new ArrayList<String>();
    static ArrayList<String> Steps = new ArrayList<String>();


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        View v = inflater.inflate(R.layout.fragment_list, container, false);

        // connect object of listview and listview id on xml
        list = (ListView) v.findViewById(android.R.id.list);


        wla = new WorkoutListAdapter(getActivity());

        // get value that passed from previous page
    //  Bundle bundle = getArguments();
        Toast.makeText(getActivity(), "arguments  "+this.getArguments(), Toast.LENGTH_SHORT).show();

        SelectedID = getArguments().getInt("selectedID",0);
                //bundle.getInt("selectedID",0);


        // call asynctask class to get data from database
        new getWorkoutList().execute();



        // listener to get selected id when list item long clicked
        list.setOnItemLongClickListener(new OnItemLongClickListener() {

            @Override
            public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
                    int position, long arg3) {
                // TODO Auto-generated method stub
                SelectedPosition = position;
                addDialog();
                return false;
            }
        });
        return v;
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        // TODO Auto-generated method stub
        super.onListItemClick(l, v, position, id);
        Intent i = new Intent(getActivity(), DetailWorkoutActivity.class);
        i.putExtra("selectedID", position);
        startActivity(i);

    }

    public static WorkoutListFragment newInstance() {
        WorkoutListFragment wo = new WorkoutListFragment();
        return wo;
    }





    // asynctask class that is used to fetch data from database in background
    public class getWorkoutList extends AsyncTask<Void, Void, Void>{

        ProgressDialog progress;

        @Override
         protected void onPreExecute() {
          // TODO Auto-generated method stub

            // show progress dialog when fetching data from database
            progress= ProgressDialog.show(
                    getActivity(), 
                    "", 
                    getString(R.string.loading_data), 
                    true);
        }

        @Override
        protected Void doInBackground(Void... params) {
            // TODO Auto-generated method stub
            getDataFromDatabase();
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            // TODO Auto-generated method stub

            // when finishing fetching data, close progress dialog and show data on listview
            // if available, otherwise show toast message
            progress.dismiss();
            if(WorkoutID.size() != 0){
                setListAdapter(wla);
                //list.setAdapter(wla);
            }else{
                Toast.makeText(getActivity(), getString(R.string.no_data_workout), Toast.LENGTH_SHORT).show();
            }
        }
    }

    // method to create arraylist variables before used
    void clearData(){
        WorkoutID.clear();
        Name.clear();
        Image.clear();
        Time.clear();
        Steps.clear();
    }

    // method to fetch data from database
    public void getDataFromDatabase(){
        data = HomeActivity.dbWorkouts.getWorkoutListByCategory(SelectedID);

        clearData();

        // store data to arraylist variables
        for(int i=0;i<data.size();i++){
            ArrayList<Object> row = data.get(i);

            WorkoutID.add(Integer.parseInt(row.get(0).toString()));
            Name.add(row.get(1).toString());
            Image.add(row.get(2).toString());
            Time.add(row.get(3).toString());
            Steps.add(row.get(4).toString());
        }

    }

    // method to create add dialog
    void addDialog(){
        String title = getString(R.string.pick_day);
        String[] day_name = getResources().getStringArray(R.array.day_name);
        String positive = getString(R.string.add);
        String negative = getString(R.string.cancel);

        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

        // set the dialog title
        builder.setTitle(title);

        // specify the list array
        builder.setSingleChoiceItems(day_name, SelectedDayID, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                // TODO Auto-generated method stub

                // get selected day
                SelectedDayID = which;
            }
        });

        // set positive button
        builder.setPositiveButton(positive, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {
                String[] day_name = getResources().getStringArray(R.array.day_name);

                // check if data already available in this day program
                boolean isAvailable = HomeActivity.dbPrograms.isDataAvailable(SelectedDayID, WorkoutID.get(SelectedPosition));

                // if data is not available add data to this day program, otherwise, show toast message
                if(!isAvailable){
                    HomeActivity.dbPrograms.addData(WorkoutID.get(SelectedPosition), Name.get(SelectedPosition), 
                                            SelectedDayID, Image.get(SelectedPosition), 
                            Time.get(SelectedPosition), Steps.get(SelectedPosition));
                    Toast.makeText(getActivity(), getString(R.string.success_add)+" "+day_name[SelectedDayID], Toast.LENGTH_SHORT).show();
                }else{
                    Toast.makeText(getActivity(), getString(R.string.failed_add)+" "+day_name[SelectedDayID], Toast.LENGTH_SHORT).show();
                }
            }
        });
        // set negative button
        builder.setNegativeButton(negative, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {
                // close update dialog if cancel button clicked
                dialog.dismiss();
            }
        });

        // show dialog
        AlertDialog alert = builder.create();
        alert.show();
    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        if (ads != null) {
            ads.destroy();
        }
        super.onDestroy();

    }
}

BaseFragment

public class BaseFragment extends ListFragment {

    private boolean mShowingChild;

    //protected PageFragmentListener mListener;

    public boolean isShowingChild() {
        return mShowingChild;
    }

    public void setShowingChild(boolean showingChild) {
        mShowingChild = showingChild;
    }

}

1 个答案:

答案 0 :(得分:0)

我在getItemPosition(Object object)中的类TabsPagerAdapter上找到了解决方案,我所做的就是添加额外的代码

  

else if(对象instanceof WorkoutListFragment)           {             return POSITION_NONE;           }

正如他们所说,如果你想要完成某些事情,你必须自己做。