在ViewPager中替换Fragment会显示空白屏幕?

10
我在使用选项卡/滑动时遇到了许多与片段相关的问题。我有一个活动和两个片段,其中一个有一个ListView。我想要的是,当我从片段1向右滑动到具有ListView的片段时,刷新ListView或者如果可能的话重新创建第二个片段...
我现在正在尝试使用FragmentTransaction.replace()来实现:
public void onTabSelected(Tab arg0, android.app.FragmentTransaction arg1) {
    // TODO Auto-generated method stub

    Fragment frag = new FragmentTwo();

    FragmentTransaction trans = getSupportFragmentManager().beginTransaction();

    if (arg0.getPosition() == 1) {
        trans.replace(R.id.pager, frag);
        trans.addToBackStack(null);
        trans.commit();
    }   
}

我认为当我滑动到带有ListView的第二个选项卡时,它会用新的选项卡替换它创建的旧选项卡。但实际上发生的是,当我划到第二个选项卡时,它会重新创建带有ListView的片段(我知道这一点,因为在onCreateView中有一个对话框显示在屏幕上),但是然后该片段/选项卡变成了空白/黑色。我做错了什么?这个被创建的片段去哪里了?

我不知道片段的代码是否相关,但如果需要请告诉我,我可以贴出来。这是我的PagerAdapter类。

public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
    super(fm);
}

@Override
public Fragment getItem(int index) {

    switch (index) {
    case 0:
        return new FragmentOne();
    case 1:
        return new FragmentTwo();
    case 2:
        return new FragmentThree();
    }
    return null;
}

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

感谢任何帮助!我真的为这个问题苦恼 :(

编辑:

当您从选项卡1滑动到选项卡2时,选项卡2会显示我的对话框,然后加载该选项卡,但如果我回到选项卡1,它就全部变黑...然后如果我再次转到选项卡2,它会再次创建并显示我的对话框,然后再次变黑...

编辑:(添加listview片段代码)

public class FragmentTwo extends Fragment {

// Progress Dialog
private ProgressDialog pDialog;

// Creating JSON Parser object
JSONParser_Helpers2 jParser = new JSONParser_Helpers2();

ArrayList<HashMap<String, String>> tripList;

// url to get all products list
private static String url_all_trips = "http://10.0.2.2/android_connect/get_all_trips.php";

// JSON Node names
private static final String TAG_SUCCESS = "success";
private static final String TAG_TRIPS = "trips";
private static final String TAG_TRIPID = "tripid";
private static final String TAG_TRIPNAME = "tripName";
private static final String TAG_UID = "uid32";

// products JSONArray
JSONArray trips = null;

View rootView;
Button btnRefresh;


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    //View rootView = inflater.inflate(R.layout.fragment_one, container, false);

    rootView = inflater.inflate(R.layout.fragment_two, container, false);
    btnRefresh = (Button) rootView.findViewById(R.id.refresh);

    // Hashmap for ListView
    tripList = new ArrayList<HashMap<String, String>>();

    // Loading products in Background Thread
    new LoadAllProducts().execute();

    // Get listview
    ListView lv = (ListView) rootView.findViewById(R.id.list);


    // on seleting single product
    // launching Edit Product Screen
    lv.setOnItemClickListener(new OnItemClickListener() {

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        //getting values from selected ListItem
        String tripid = ((TextView) view.findViewById(R.id.pid)).getText().toString();

        //starting new intent
        Intent in = new Intent(getActivity(), EditTrip_Activity.class);
        //sending pid to next activity
        in.putExtra(TAG_TRIPID, tripid);

        //starting new activity and expecting some response back
        startActivityForResult(in, 100);
    }

    });
    return rootView;
}

/**
 * Background Async Task to Load all product by making HTTP Request
 * */
class LoadAllProducts extends AsyncTask<String, String, String> {

    ListView lv = (ListView) rootView.findViewById(R.id.list);
    /**
     * Before starting background thread Show Progress Dialog
     * */
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(getActivity());
        pDialog.setMessage("Loading your trips. Please wait...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(false);
        pDialog.show();
    }

    /**
     * getting All products from url
     * */
    protected String doInBackground(String... args) {
        // Building Parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        // getting JSON string from URL
        JSONObject json = jParser.makeHttpRequest(url_all_trips, "GET", params);

        // Check your log cat for JSON response
        Log.d("All Trips: ", json.toString());

        try {
            // Checking for SUCCESS TAG
            int success = json.getInt(TAG_SUCCESS);

            if (success == 1) {
                // products found
                // Getting Array of Products
                trips = json.getJSONArray(TAG_TRIPS);

                // looping through All Products
                for (int i = 0; i < trips.length(); i++) {
                    JSONObject c = trips.getJSONObject(i);

                    // Storing each json item in variable
                    String tripid = c.getString(TAG_TRIPID);
                    String tripname = c.getString(TAG_TRIPNAME);
                    String userId = c.getString("uid");

                    // creating new HashMap
                    DatabaseHandler_Helpers db = new DatabaseHandler_Helpers(getActivity());
                    HashMap<String, String> map = new HashMap<String, String>();

                    if (userId.equals(db.getUserDetails().get("uid"))) {
                        // adding each child node to HashMap key => value
                        map.put(TAG_TRIPID, tripid);
                        map.put(TAG_TRIPNAME, tripname);

                        // adding HashList to ArrayList
                        tripList.add(map);
                    } //else {
                        //map.put(TAG_TRIPID, "");
                        //map.put(TAG_TRIPNAME, "You have no tracked trips.");

                        //tripList.add(map);
                    //}
                }
            } else {
                // no products found
                // Launch Add New product Activity
                Intent i = new Intent(getActivity(),
                        NewTrip_Activity.class);
                // Closing all previous activities
                i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(i);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * After completing background task Dismiss the progress dialog
     * **/
    protected void onPostExecute(String file_url) {
        // dismiss the dialog after getting all products
        pDialog.dismiss();

        // updating UI from Background Thread
        ((Activity) getActivity()).runOnUiThread(new Runnable() {
            public void run() {
                /**
                 * Updating parsed JSON data into ListView
                 * */

                ListAdapter adapter = new SimpleAdapter(
                        getActivity(), tripList,
                        R.layout.list_item, new String[] { TAG_TRIPID,
                                TAG_TRIPNAME},
                        new int[] { R.id.pid, R.id.name });
                // updating listview
                ((ListView) lv.findViewById(R.id.list)).setAdapter(adapter);
            }
        });
     }
 }

}


主要是将以下代码:public class TabsPagerAdapter extends FragmentPagerAdapter替换为:public class TabsPagerAdapter extends FragmentStatePagerAdapter:) - mike20132013
你是否正在使用父片段和子片段? - user2511882
4个回答

15

尝试使用FragmentStatePagerAdapter来扩展,而不是FragmentPagerAdapter。

以下是我的代码用于片段,对我来说运行良好:

//Adapter
public class AllPagesAdapter extends FragmentStatePagerAdapter {



            public AllPagesAdapter(FragmentManager fm) {

                super(fm);

            }

            @Override
            public Fragment getItem(int index) {

        switch (index) {
            case 0:

                return new Android();

            case 1:

                return new CoreJava();
            case 2:

                return new J2EE();

            case 3:

                return new Database();

            case 4:

                return new WebServices();


        }
        return null;


    }

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

}

//For example, this is one fragment:

public class Database extends Fragment {

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

        View databaseview = inflater.inflate(R.layout.database, container, false);

        return databaseview;

    }


}

//My MainActivity

public class AllActivities extends FragmentActivity implements ActionBar.TabListener {

    public ViewPager viewPager;
    private AllPagesAdapter mAdapter;
    private ActionBar actionBar;
    private String [] tabs = {"Android","CoreJava","J2EE","Database","Web Services"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Initializing all stuff
        viewPager = (ViewPager)findViewById(R.id.pager);

        actionBar = getActionBar();
        mAdapter = new AllPagesAdapter(getSupportFragmentManager());
        viewPager.setAdapter(mAdapter);
        actionBar.setHomeButtonEnabled(true);
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);



        //Add the tabs here
        for(String tab_name:tabs){
            actionBar.addTab(actionBar.newTab().setText(tab_name).setTabListener(this));
        }

        viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){

            @Override
        public void onPageSelected(int position){

                //on Page change, that particular page should be selected
                actionBar.setSelectedNavigationItem(position);
            }

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

            }
            @Override
        public void onPageScrollStateChanged(int position){

            }

        });
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction fragmentTransaction) {

        viewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction fragmentTransaction) {



    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction fragmentTransaction) {

        viewPager.setCurrentItem(tab.getPosition());

    }
}

如果你也想要在任何一个片段中实现列表视图,请让我知道。

希望这有所帮助...:)


谢谢Mike!我有和你差不多的代码,现在我改成了FragmentStatePagerAdapter,现在所有的选项卡都能加载并且我可以在它们之间滑动,但问题是当我滑到第二个选项卡时,我的listview没有更新...调用更新listview的函数是在onCreateView()方法中完成的...我应该移动它吗?我尝试将调用放置在我的片段内的onResume()中,但仍然没有运气! - user2573690
让我试着执行你的代码,看看到底发生了什么... :) 不用担心,这种情况也曾经发生在我身上,很快就解决了。 - mike20132013
有什么进展吗?我设法让loadAllProducts()无限循环,但仍然无法在切换选项卡时加载产品。 - user2573690
我已经发布了我的代码,您可以查看它,如果有任何疑问,请告诉我。我刚刚发布了整个代码,但并没有包括XML。 - mike20132013
你尝试在清单文件中设置标志了吗?你可以设置标志为 Android:noHistory = "true",类似这样的东西。你会在那里看到它,或者也可以尝试在你要设置的意图中设置。例如:Intent i = new Intent(......something); i.addFlag(Intent.yourflag as no history)。 - mike20132013
显示剩余2条评论

4

我的子片段在ViewPager中。我只是用FragmentStatePagerAdapter替换了ViewPage适配器,而不是使用FragmentPagerAdapter

子片段 ....

mViewPager.setAdapter(new SearchOriginTabsPagerAdapter(getFragmentManager()));

Adapter...

public class SearchOriginTabsPagerAdapter extends FragmentStatePagerAdapter {

public SearchOriginTabsPagerAdapter(FragmentManager fm) {
    super(fm);
}

@Override
public Fragment getItem(int index) {

    switch (index) {
    case 0:
        return new NearbyFragment();
    case 1:
        return new RecentOriginFragment();
    }

    return null;
}

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

0

好的.. 其实是这样的..

我并没有真正使用你的代码,而是使用了类似的概念。这将是一个完整的解决方案。

//这是应用程序的起点。它包含许多片段,并且我正在使用自己的 JSON 来获取数据。

public class AllActivities extends FragmentActivity implements ActionBar.TabListener {

    public ViewPager viewPager;
    private AllPagesAdapter mAdapter;
    private ActionBar actionBar;
    private String [] tabs = {"Android","CoreJava","J2EE","Database","Web Services"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Initializing all stuff
        viewPager = (ViewPager)findViewById(R.id.pager);

        actionBar = getActionBar();
        mAdapter = new AllPagesAdapter(getSupportFragmentManager());
        viewPager.setAdapter(mAdapter);
        actionBar.setHomeButtonEnabled(true);
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);



        //Add the tabs here
        for(String tab_name:tabs){
            actionBar.addTab(actionBar.newTab().setText(tab_name).setTabListener(this));
        }

        viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){

            @Override
        public void onPageSelected(int position){

                //on Page change, that particular page should be selected
                actionBar.setSelectedNavigationItem(position);
            }

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

            }
            @Override
        public void onPageScrollStateChanged(int position){

            }

        });
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction fragmentTransaction) {

        viewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction fragmentTransaction) {



    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction fragmentTransaction) {

        viewPager.setCurrentItem(tab.getPosition());

    }
}

//This is one of the fragment and assume that Expandablelistview is your list view.. In both the cases, i am setting the adapter in the onActivityCreated() method.
public class Android extends android.support.v4.app.Fragment {



    ExpandableListAdapter listAdapter;
    // private ExpandableListView expListView;
    List<String> listDataHeader;
    HashMap<String, List<String>> listDataChild;
    ListView lv1;
    private static final String QUESTION = "question";
    private static final String ANSWERS = "answer";


    // ArrayList<HashMap<String, String>> jsonlist = new ArrayList<HashMap<String, String>>();

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


        View mikeview = inflater.inflate(R.layout.androidlayout, container, false);

        return mikeview;

    }



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


        ExpandableListView expListView = null;
        try{
            expListView = (ExpandableListView) getActivity().findViewById(R.id.androidExpandableList);
            }
        catch (Exception e){

            e.printStackTrace();
        }




        new Thread(){


            @Override
            public void run(){



            }
        }.start();

        try {
            setParent();
            prepareChild();
        } catch (Exception e) {
            e.printStackTrace();
        }




        ExpandableListAdapter listAdapter = new ExpandableListAdapter(getActivity(), listDataHeader, listDataChild);
        expListView.setAdapter(listAdapter);




        // Listview on child click listener
        expListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {

            @Override
            public boolean onChildClick(ExpandableListView parent, View v,
                                        int groupPosition, int childPosition, long id) {
                /*Toast.makeText(
                        getActivity(),
                        listDataHeader.get(groupPosition)
                                + " : "
                                + listDataChild.get(
                                listDataHeader.get(groupPosition)).get(
                                childPosition), Toast.LENGTH_SHORT)
                        .show();*/
                return true;
            }
        });


        // Listview Group expanded listener
        expListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {

            @Override
            public void onGroupExpand(int groupPosition) {
               /* Toast.makeText(getActivity(),
                        listDataHeader.get(groupPosition) + " Expanded",
                        Toast.LENGTH_SHORT).show();*/
            }
        });

        // Listview Group collasped listener
        expListView.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {

            @Override
            public void onGroupCollapse(int groupPosition) {
                /*Toast.makeText(getActivity(),
                        listDataHeader.get(groupPosition) + " Collapsed",
                        Toast.LENGTH_SHORT).show();*/

            }
        });


    }


    public void setParent(){

        listDataHeader = new ArrayList<String>();

        try{

            JSONObject json = new JSONObject(loadJSONFromAsset());

            JSONArray array = json.getJSONArray("androidquestion");

            for(int my =0;my<array.length();my++){

                JSONObject c = array.getJSONObject(my);


                String topics = c.getString(QUESTION);
                listDataHeader.add(topics);
            }
        }

        catch (JSONException e) {

            e.printStackTrace();

        }

    }

    public void prepareChild() throws JSONException {

        listDataChild = new HashMap<String, List<String>>();

        try{

            JSONObject json = new JSONObject(loadJSONFromAsset());
            JSONArray array = json.getJSONArray("androidquestion");
            for(int mz = 0;mz<array.length();mz++){

                ArrayList<String> child = new ArrayList<String>();
                JSONObject d = array.getJSONObject(mz);
                String ans = d.getString(ANSWERS);
                child = new ArrayList<String>();

                child.add(ans);
                int position = mz ;

                listDataChild.put(listDataHeader.get( position),child);

            }
        }
        catch(JSONException e) {
            e.printStackTrace();

        }

    }


    public String loadJSONFromAsset() {

        String json = null;

        try {

            InputStream is = getActivity().getAssets().open("android.json");

            int size = is.available();

            byte[] buffer = new byte[size];

            is.read(buffer);

            is.close();

            json = new String(buffer, "UTF-8");

        } catch (IOException ex) {

            ex.printStackTrace();

            return null;
        }
        return json;

    }

}

    //This is the adapter.
    public class AllPagesAdapter extends FragmentStatePagerAdapter {



            public AllPagesAdapter(FragmentManager fm) {

                super(fm);

            }

            @Override
            public Fragment getItem(int index) {

        switch (index) {
            case 0:

                return new Android();

            case 1:

                return new CoreJava();
            case 2:

                return new J2EE();

            case 3:

                return new Database();

            case 4:

                return new WebServices();


        }
        return null;


    }

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

}

//This is the adapter for my expandable list view.. in your case, your can just use the listadapter or any other adapter you want to use. This is just an optional part.
public class ExpandableListAdapter extends BaseExpandableListAdapter {

    private Context _context;
    private List<String> _listDataHeader; // header titles
    // child data in format of header title, child title
    private HashMap<String, List<String>> _listDataChild;


    public ExpandableListAdapter(Context context, List<String> listDataHeader,
                                 HashMap<String, List<String>> listChildData) {
        this._context = context;
        this._listDataHeader = listDataHeader;
        this._listDataChild = listChildData;
    }

    @Override
    public Object getChild(int groupPosition, int childPosititon) {
        return this._listDataChild.get(this._listDataHeader.get(groupPosition))
                .get(childPosititon);
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    @Override
    public View getChildView(int groupPosition, final int childPosition,
                             boolean isLastChild, View convertView, ViewGroup parent) {

        final String childText = (String) getChild(groupPosition, childPosition);

        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) this._context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.newlistitems,null);

        }

        TextView txtListChild = (TextView) convertView
                .findViewById(R.id.newlistviewitems);

        txtListChild.setText(childText);
        return convertView;
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        return this._listDataChild.get(this._listDataHeader.get(groupPosition))
                .size();
    }

    @Override
    public Object getGroup(int groupPosition) {
        return this._listDataHeader.get(groupPosition);
    }

    @Override
    public int getGroupCount() {
        return this._listDataHeader.size();
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded,
                             View convertView, ViewGroup parent) {
        String headerTitle = (String) getGroup(groupPosition);
        if (convertView == null) {
            LayoutInflater myInflater = (LayoutInflater) this._context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = myInflater.inflate(R.layout.newlistgroup, null);
        }

        TextView lblListHeader = (TextView) convertView
                .findViewById(R.id.newlistviewgroup);
        lblListHeader.setTypeface(null, Typeface.BOLD);
        lblListHeader.setText(headerTitle);

        return convertView;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }
}

所以基本上你是在onActivityCreated中填充listview吗?我的意思是调用方法来解析JSON并填充列表?我尝试将相同的方法添加到我的片段中,但仍然没有任何作用,当第一个选项卡/片段加载时,列表最初被填充,然后在切换到它时不再加载。 - user2573690
是的,但在你的情况下非常奇怪,因为我曾经遇到过与我的ListView相同的问题,但是在使用FragmentStatePagerAdapter之后,它正常工作了。 - mike20132013
是的,确实很奇怪,我尝试了很多方法,但什么都不起作用。我在清单中设置了noHistory,但仍然没有效果:(。 - user2573690

0

如果有人使用viewpager2,则使用以下构造函数。 FragmentStateAdapter(fragmentManager,lifecycle)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接