繁体   English   中英

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

[英]How to handle Back Button press in android fragments

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

这是我的代码:

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

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

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

        }
    }

}

我认为你可以这样做:

创建一个通用片段:

public abstract class extends BaseFragment {

    public abstract boolean  onBackPressed();

}

在他的 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;
    }
}

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

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

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

}

改变你的情况!

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

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

在这种情况下,你可能想看看在片段的其他生命周期回调,因为有其中一个片段的视图可以被毁灭,但用户没有按返回其他领域。 当 Fragment 从 Activity 的 FragmentManager 中移除并正在清理资源时,将调用onDestroyView() onPause()onStop()也是不错的选择。

但是,要回答主要问题,通常这是通过在您的 Activity 中覆盖onBackPressed来完成的。 您的 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();
}

Kotlin 解决方案

lateinit var onBackpressedCallBack: OnBackPressedCallback

onBackpressedCallBack = object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            customDialog.showDialog()
        }
    }

    requireActivity().onBackPressedDispatcher.addCallback(onBackpressedCallBack)

对于 KOTLIN,这里是代码片段

override fun onAttach(context: Context) {
    super.onAttach(context)
    val callback: OnBackPressedCallback = object :
        OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            TODO("your code here...")
        }
    }
    requireActivity().onBackPressedDispatcher.addCallback(this, callback)
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM