【发布时间】:2016-12-14 13:38:26
【问题描述】:
我正在使用 Android 片段在我的应用程序中加载代码。要创建一个简单的加载器,我有LoadingFragment extends Fragment,然后我的片段类扩展了它,例如:MyFragment extends LoadingFragment。
LoadingFragment 有 hideLoader 和 showLoader,理论上我的子类 Fragment 应该能够调用 onCreateView 和 onPostExecute 以在加载之间显示和隐藏进度条。
布局方面,我有一个main_layout.xml,它有一个用于动态片段的框架布局和一个用于容纳进度条的静态相对布局。
目前,我的片段在元素的点击中从另一个内部加载和替换,但我已经删除了该代码。
问题
问题是LoadingFragment 中的setVisibilty 在从子类调用时似乎效果为零,例如MyFragment,这是为什么呢?
我已经给了LoadingFragment 它自己的View 变量viewMaster,我认为它应该引用main_layout,但可见性变化似乎仍然没有效果?
MainActivity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyFragment myFragment = MyFragment.newInstance();
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_holder, myFragment).commit();
}
}
加载片段
public class LoadingFragment extends Fragment {
View viewMaster;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
viewMaster = inflater.inflate(R.layout.main_layout, container, false);
return viewMaster;
}
public void showLoader() {
viewMaster.findViewById(R.id.fragment_holder).setVisibility(View.INVISIBLE);
viewMaster.findViewById(R.id.loading).setVisibility(View.VISIBLE);
}
public void hideLoader() {
viewMaster.findViewById(R.id.fragment_holder).setVisibility(View.VISIBLE);
viewMaster.findViewById(R.id.loading).setVisibility(View.INVISIBLE);
}
}
我的片段
public class MyFragment extends LoadingFragment {
View view;
public MyFragment() {}
public static MyFragment newInstance() {
MyFragment fragment = new MyFragment();
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
super.showLoader();
view = inflater.inflate(R.layout.fragment_lans, container, false);
MyFragment.ApiCallJob apicalljob = new MyFragment.ApiCallJob();
apicalljob.execute("a string");
return view;
}
public class ApiCallJob extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String[] params) {
// do things
}
@Override
protected void onPostExecute(String data) {
// do things
// tried both to be sure but they should do the same?
hideLoader();
MyFragment.super.hideLoader();
}
}
}
main_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="app.stats.MainActivity"
android:orientation="horizontal">
<FrameLayout
android:id="@+id/fragment_holder"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
<RelativeLayout
android:id="@+id/loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ProgressBar
style="?android:attr/progressBarStyleLarge"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/progress_bar"/>
</RelativeLayout>
</RelativeLayout>
【问题讨论】:
-
不要在 wrap_content 中使用 match_parent
-
"问题是从子类调用时,LoadingFragment 中的 setVisibilty 似乎效果为零,例如 MyFragment" 这是什么意思?您能否描述一个用例,包括用户采取的确切步骤、期望的行为以及实际结果?
-
我也是为什么你在这里使用继承?您在不同片段之间共享哪些属性?
-
@Code-Apprentice 的想法是在上部主模板中有 1 个进度条,例如,当它们通过 api http 请求加载内容时,可以将其用作所有片段。这是我能想到的减少重复代码的唯一方法。
-
另外,您要尽量减少重复的代码?我建议你做一些工作,即使它有重复的代码。您可以稍后重构重复项。这是一种常见的技术,尤其是在测试驱动开发中。即使您实际上并没有首先编写测试,您仍然可以使用重构步骤来获得很好的效果。
标签: android android-layout android-fragments