我在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;
}
}
答案 0 :(得分:0)
我在getItemPosition(Object object)中的类TabsPagerAdapter上找到了解决方案,我所做的就是添加额外的代码
else if(对象instanceof WorkoutListFragment) { return POSITION_NONE; }
正如他们所说,如果你想要完成某些事情,你必须自己做。