Android 开发中使用Fragment跳转到下一个Fragment,并实现返回键和自定义返回键。
项目结构:
主类:
MainActivity
FirstFragment
SecondFragment
辅助文件:
BackHandledInterface.java
BackHandledFragment .java
实现逻辑
入口:MainActivity中包含MainFragment并且能跳转到SecondFragment
返回:SecondFragment ---> MainFragment--->结束当前activity;
初衷:
看到 Android 使用Fragment界面向下跳转并一级级返回 一文中,作者使用 replace()方法实现fragment的跳转,本人项目中需要使用add(), hiden()方法所以寻求改变思路。
解决方案如下:
BackHandledInterface.java保持不变
public interface BackHandledInterface {
public abstract void setSelectedFragment(BackHandledFragment selectedFragment);
}
BackHandledFragment.java, 如下
public abstract class BackHandledFragment extends Fragment {
protected BackHandledInterface mBackHandledInterface;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!(getActivity() instanceof BackHandledInterface)) {
throw new ClassCastException(
"Hosting Activity must implement BackHandledInterface");
} else {
this.mBackHandledInterface = (BackHandledInterface) getActivity();
}
}
@Override
public void onStart() {
super.onStart();
// 告诉FragmentActivity,当前Fragment在栈顶
mBackHandledInterface.setSelectedFragment(this);
}
@Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);//如果hidden为true则隐藏,否则显示
if (!hidden) {
mBackHandledInterface.setSelectedFragment(this);
}
}
}
我 重写了onHidden方法因为当每次在fragment在调用show() 和hidden()方法都会调用此方法。 show() 和hidden()并不会调用onStart(),所以不重新则无法告诉FragmentActivity,当前Fragment在栈顶.
主界面MainActivity,我集成了AppCompatActivity,兼容类。
</pre><pre name="code" class="java">public class MainActivity extends AppCompatActivity implements
BackHandledInterface {
private static MainActivity mInstance;
private BackHandledFragment mBackHandedFragment;
private Button btnSecond;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
android.support.v4.app.Fragment fragment = new FirstFragment();
getSupportFragmentManager().beginTransaction().add(R.id.bus_content, fragment, <pre name="code" class="java">"tag"
).commit();
bt_back= (ImageView) findViewById(R.id.back);
bt_back.setVisibility(View.VISIBLE);
bt_back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mBackHandedFragment.getClass().getSimpleName().toString().equals("FirstFragment.getClass().getSimpleName().toString()
")){
finish();//如果当前为FirstFragment怎退出activity
}else {
getSupportFragmentManager().popBackStack();//否则把顶部的状态弹出回退堆栈
}
}
});
}
@Override
public void setSelectedFragment(BackHandledFragment selectedFragment) {
this.mBackHandedFragment = selectedFragment;
}
}
FirstFragment.java
public class FirstFragment extends BackHandledFragment implements View.OnClickListener {
//四个button
private ImageView bt_RouteQuery;
public BusMainFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_bus_main, container, false);
bt_RouteQuery = (ImageView) rootView.findViewById(R.id.imgbtn_routequery);
bt_RouteQuery.setOnClickListener(this);
return rootView;
}
@Override
public void onClick(View v) {
String tag;
switch (v.getId()) {
case R.id.imgbtn_routequery:
tag = FragmentFactory.BusRouteFragment;
getActivity().getSupportFragmentManager().beginTransaction()
.hide(this)
.add(R.id.bus_content, new SecondFragment(), <pre name="code" class="java">"tag")
) .addToBackStack(null)//增加到回退栈,官方的说法是取决于你是否要在回退的时候显示上一个Fragment,此句话我实现了物理返回键返回到上个fragment .commit(); break; default: break; } }}
SecondFragment.java无任何需求,则不贴出来。
总结:
通过重写onHidden方法实现了,完善了自定义按钮的返回功能。以及由于add和replace的原理不一致导致的bug。
更加简单的addToBackStack(null)实现了物理返回键的返回功能。(这一点我再回去研究研究,是否存在bug,为什么前人文章不这么使用).
申明:本人刚刚从学校毕业,如有什么地方写的不对的请告诉我,让我也能进步学习。感谢