Java 如何处理android片段中的后退按钮按下

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24713957/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 14:22:49  来源:igfitidea点击:

How to handle Back Button press in android fragments

javaandroidandroid-fragments

提问by Akshat

I have a class which extends fragment. It receives a data from server and loads on the fragment layout. The data comes from AsyncTask doInBackground. But I am facing a problem that if asynctask is still doing in background and user presses back button, my app goes to another activity. But when the asynctask finishes, it does not find the needed layout and hence crashes the app. How to cancel this async task when user presses the back button in the middle of do in background, and more importantly, how to call on back pressed in fragments.

我有一个扩展片段的类。它从服务器接收数据并加载片段布局。数据来自 AsyncTask doInBackground。但是我面临一个问题,如果 asynctask 仍在后台执行并且用户按下后退按钮,我的应用程序将转到另一个活动。但是当 asynctask 完成时,它没有找到所需的布局,因此导致应用程序崩溃。当用户在后台 do 中间按下后退按钮时如何取消此异步任务,更重要的是如何调用片段中的后退按钮。

Here is my code:

这是我的代码:

TabsPagerAdapter.java

TabsPagerAdapter.java

public class TabsPagerAdapter extends FragmentPagerAdapter {

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

    @Override
    public Fragment getItem(int index) {

        switch (index) {
        case 0:
            // Top Rated fragment activity
            return new TopStoriesFragment();
        case 1:
            // Games fragment activity
            return new NationalFragment();
        case 2:
            // Movies fragment activity
            return new InternationalFragment();

        case 3:
            // Movies fragment activity
            return new SportsFragment();

        case 4:
            // Movies fragment activity
            return new TechnologyFragment();
        case 5:
            // Movies fragment activity
            return new BusinessFragment();
        case 6:
            // Movies fragment activity
            return new EntertainmentFragment();
        }


        return null;
    }

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

    public void stop() {
        // get item count - equal to number of tabs
        return;
    }

}

MainActivity.java

主活动.java

public class MainActivity extends FragmentActivity implements
        ActionBar.TabListener {

    private ViewPager viewPager;
    private TabsPagerAdapter mAdapter;
    private ActionBar actionBar;
    // Tab titles
    private String[] tabs = { "Top Stories", "National", "International", "Sports", "Technology", "Business", "Entertainment"};

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


        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) {
            }
        });
    }

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

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        // on tab selected
        // show respected fragment view
        viewPager.setCurrentItem(tab.getPosition());
    }

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

}

BusinessFragment.java

业务片段.java

public class BusinessFragment extends Fragment {

    public String thehindu = "xxxxx";
    public String toi = "xxxxx";
    public String hindustantimes = "xxxxx";
    public String indianexpress = "xxxxxx";
    public String reuters = "xxxxxxx";

    public String dainikjagaran = "xxxxxx";
    public String dainikbhaskar = "xxxxx";
    public String amarujala = "xxxxxx";

    public String currenturl;
    AlertDialog levelDialog;
    public LayoutInflater inflater;
    ListView listView;
    int mCurCheckPosition;
    SharedPreferences sp;
    String papername;

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

        View rootView = inflater.inflate(R.layout.fragment_data, container,
                false);

        sp = getActivity().getSharedPreferences("myfile",
                getActivity().MODE_PRIVATE);
        papername = sp.getString("Newspaper_name", null);

        feedTitle = (TextView) rootView.findViewById(R.id.feedtitle);
        feedDescribtion = (TextView) rootView
                .findViewById(R.id.feeddescribtion);

        getCurrentURL();

        listView = (ListView) rootView.findViewById(android.R.id.list);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View v,
                    int position, long id) {

                Intent intent = new Intent(getActivity(), ShowDetails.class);
                Bundle bundle = new Bundle();
                bundle.putString("keyTitle", myRssFeed.getItem(position)
                        .getTitle());
                bundle.putString("keyDescription", myRssFeed.getItem(position)
                        .getDescription());
                bundle.putString("keyLink", myRssFeed.getItem(position)
                        .getLink());
                bundle.putString("keyPubdate", myRssFeed.getItem(position)
                        .getPubdate());
                intent.putExtras(bundle);
                startActivity(intent);

            }
        });

        startReadRss();

        return rootView;
    }

    public class RssLoadingTask extends AsyncTask<Void, Void, Void> {

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

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

        @Override
        protected void onProgressUpdate(Void... values) {
            // TODO Auto-generated method stub
            // super.onProgressUpdate(values);
        }

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

    }

    private RSSFeed myRssFeed = null;

    TextView feedTitle;
    TextView feedDescribtion;

    // TextView feedPubdate;
    // TextView feedLink;

    public class MyCustomAdapter extends ArrayAdapter<RSSItem> {

        public MyCustomAdapter(Context context, int textViewResourceId,
                List<RSSItem> list) {
            super(context, textViewResourceId, list);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
            // return super.getView(position, convertView, parent);

            View row = convertView;

            if (row == null) {
                inflater = LayoutInflater.from(getActivity());
                row = inflater.inflate(R.layout.row, parent, false);
            }

            TextView listTitle = (TextView) row.findViewById(R.id.listtitle);
            listTitle.setText(myRssFeed.getList().get(position).getTitle());
            TextView listPubdate = (TextView) row
                    .findViewById(R.id.listpubdate);
            listPubdate.setText(myRssFeed.getList().get(position).getPubdate());

            return row;
        }
    }

    private void startReadRss() {
        new RssLoadingTask().execute();
    }

    private void getCurrentURL() {

        if (papername.equalsIgnoreCase("The Times of India")) {
            currenturl = toi;
        } else if (papername.equalsIgnoreCase("The Hindu")) {
            currenturl = thehindu;
        } else if (papername.equalsIgnoreCase("The Hindustan Times")) {
            currenturl = hindustantimes;
        } else if (papername.equalsIgnoreCase("The Indian Express")) {
            currenturl = indianexpress;
        } else if (papername.equalsIgnoreCase("Reuters")) {
            currenturl = reuters;
        } else if (papername.equalsIgnoreCase("????? ?????")) {
            currenturl = dainikjagaran;
        } else if (papername.equalsIgnoreCase("????? ??????")) {
            currenturl = dainikbhaskar;
        } else if (papername.equalsIgnoreCase("??? ?????")) {
            currenturl = amarujala;
        }
        // else if(papername.equalsIgnoreCase("Times of India"))
        // {
        //
        // }
        // else if(papername.equalsIgnoreCase("Times of India"))
        // {
        //
        // }
        //

    }

    private void preReadRss() {
        feedTitle.setText("--- wait ---");
        feedDescribtion.setText("");
        // feedPubdate.setText("");
        // feedLink.setText("");
        listView.setAdapter(null);

        // Toast.makeText(getActivity(), "Reading RSS, Please wait.",
        // Toast.LENGTH_LONG)
        // .show();
    }

    private void readRss() {

        try {
            URL rssUrl = new URL(currenturl);
            SAXParserFactory mySAXParserFactory = SAXParserFactory
                    .newInstance();
            SAXParser mySAXParser = mySAXParserFactory.newSAXParser();
            XMLReader myXMLReader = mySAXParser.getXMLReader();
            RSSHandler myRSSHandler = new RSSHandler();
            myXMLReader.setContentHandler(myRSSHandler);
            InputSource myInputSource = new InputSource(rssUrl.openStream());
            myXMLReader.parse(myInputSource);

            myRssFeed = myRSSHandler.getFeed();

        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private void displayRss() {
        if (myRssFeed != null) {
            Calendar c = Calendar.getInstance();
            // String strCurrentTiime = "\n(Time of Reading - "
            // + c.get(Calendar.HOUR_OF_DAY)
            // + " Hrs. : "
            // + c.get(Calendar.MINUTE) + " Mins.)\n" +c.get(Calendar.AM_PM);

            SimpleDateFormat sdf = new SimpleDateFormat(
                    "MMMM-dd-yyyy HH:mm:ss a");
            String strCurrentTiime = sdf.format(c.getTime());

            feedTitle.setText(papername);
            feedDescribtion.setText(strCurrentTiime);
            // feedPubdate.setText(myRssFeed.getPubdate());
            // feedLink.setText(myRssFeed.getLink());

            MyCustomAdapter adapter = new MyCustomAdapter(getActivity(),
                    R.layout.row, myRssFeed.getList());
            listView.setAdapter(adapter);

        }
    }

}

采纳答案by Cícero Moura

I think you can do this:

我认为你可以这样做:

Create a generic Fragment:

创建一个通用片段:

public abstract class extends BaseFragment {

    public abstract boolean  onBackPressed();

}

In his Fragments, extends this BaseFragment, example:

在他的 Fragments 中,扩展了这个 BaseFragment,例如:

public class TopStoriesFragment extends BaseFragment {

    ...


    @Override
    public boolean onBackPressed()
    {
       //if you return false, then it is because you have not consumed 
       //the event, but if it          returns true, which is consumed by this event.
        return false;
    }
}

In his MainActivity activity, you should check in onBackPressed event, if the event was consumed or not, to decide what to do.

在他的 MainActivity 活动中,您应该检查 onBackPressed 事件,无论该事件是否被消耗,以决定要做什么。

It is very important that you save the current tab!

保存当前选项卡非常重要!

public class MainActivity extends FragmentActivity implements
        ActionBar.TabListener {

       //It is very important that you save the current tab!
       private BaseFragment currentTab;

     // ...  implementation 



public class TabsPagerAdapter extends FragmentPagerAdapter {

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

    @Override
    public Fragment getItem(int index) {

         currentTab = null;

        switch (index) {
        case 0:
            // Top Rated fragment activity
            currentTab = new TopStoriesFragment();
       break;
        case 1:
            // Games fragment activity
            return new NationalFragment();
        case 2:
            // Movies fragment activity
            currentTab = new InternationalFragment();
          break;
        case 3:
            // Movies fragment activity
            currentTab = new SportsFragment();
           break;
        case 4:
            // Movies fragment activity
            currentTab = new TechnologyFragment();
        case 5:
            // Movies fragment activity
            currentTab = new BusinessFragment();
         break;
        case 6:
            // Movies fragment activity
            currentTab = new EntertainmentFragment();
        break;
        }


        return currentTab;
    }

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

    public void stop() {
        // get item count - equal to number of tabs
        return;
    }

}


@Override
public void onBackPressed() 
{
  //If the event returned false, then call the super.
  if(currentTab == null || !currentTab.onBackPressed())
  super.onBackPressed();
}

}

Change to your case!

改变你的情况!

回答by erik

Its probably a good idea to use onPause actually, because your activity could be killed while in the background after a home press as well.

实际上使用 onPause 可能是一个好主意,因为您的活动也可能在主页按下后在后台被终止。

AsyncTasks can be canceled by saying myAsyncTask.cancel(true);

AsyncTasks 可以通过说取消 myAsyncTask.cancel(true);

回答by DeeV

In this case you may want to look at the other lifecycle callbacks of Fragments because there are other areas where a Fragment's View can be destroyed but the user did notpress back. onDestroyView()is called when the Fragments have been removed from the Activity's FragmentManager and is cleaning up resources. onPause()and onStop()are also good candidates.

在这种情况下,你可能想看看在片段的其他生命周期回调,因为有其中一个片段的视图可以被毁灭,但用户做了其他方面按后退。 onDestroyView()当 Fragment 从 Activity 的 FragmentManager 中移除并正在清理资源时调用。 onPause()并且onStop()也是很好的候选人。

However, to answer the main question, usually this is done by overriding onBackPressedin your Activity. Your Fragment would inherit from an interface you make called BackPressedListeneror whatever which has a callback for back pressed.

但是,要回答主要问题,通常这是通过覆盖onBackPressed您的 Activity来完成的。您的 Fragment 将从您调用的接口BackPressedListener或任何具有回调的接口继承。

// In your main Activity
@Override
public void onBackPressed() {
   // There's unfortunately no good way to loop through active fragment from the FragmentManager, so you'll have to come up with a strategy on which fragments to get.
   BackPressedFragment frag = getBackPressedFragment();
   frag.onBackPressed();

   super.onBackPressed();
}

public class BackPressedFragment implements BackPressedListener {

   @Override
   public void onBackPressed() {
      Log.i("TAG", "The back button was pressed!");
   }
}

public interface BackPressedListener {
   public void onBackPressed();
}