Dan*_*Dan 4 android android-layout android-fragments
我正在使用Android片段加载我的应用程序中的代码.要创建一个简单的加载器LoadingFragment extends Fragment
,然后我的片段类扩展它,例如:MyFragment extends LoadingFragment
.
将LoadingFragment
具有hideLoader
与showLoader
理论上我的子类片段应该能够在来电onCreateView
和onPostExecute
来显示和隐藏在负载之间的进度条.
布局明智我有一个main_layout.xml
动态片段的framelayout和一个包含进度条的静态relativelayout.
目前我的片段加载并从另一个内部替换元素,但我删除了该代码.
问题
这个问题是setVisibilty
在LoadingFragment
似乎从子类中调用它时,例如具有零效果MyFragment
,这是为什么?
我已经给出了LoadingFragment
它自己的View
变量viewMaster
,我认为应该参考main_layout
但仍然可见性变化似乎没有效果?
主要活动
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();
}
}
Run Code Online (Sandbox Code Playgroud)
LoadingFragment
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);
}
}
Run Code Online (Sandbox Code Playgroud)
MyFragment
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
这个问题是
setVisibility
在LoadingFragment
似乎从子类中调用它时,例如具有零效果MyFragment
,这是为什么?
让我们来看看MyFragment onCreateView
调用时会发生什么:
你打电话给super
onCreateView
哪个LoadingFragment
.这会膨胀main_layout
并返回膨胀的视图.请注意,此视图未在MyFragment
(即View mainLayout = super.onCreateView(inflater, container, savedInstanceState);
)中 引用
您刚刚对具有loading
视图组的视图进行了充气,然后将其丢弃.但是,您确实设法在LoadingFragment
超类中保存对该视图的引用.
接下来你膨胀R.layout.fragment_lans
并且(在开始加载之后)将该视图作为要在片段中使用的视图返回.
所以在这里要观察的是,LoadingFragment
现在有一个对片段的活动视图层次结构中没有的视图的引用.
鉴于此,难怪setVisibility
不会做任何事情,因为片段没有显示该视图.
我不会使用继承来做这件事,但如果你必须使用它,这里是如何解决你的问题.
我们只使用ProgressBar
没有视图组包装器.因为它在a中RelativeLayout
,让我们把它放在中心位置.然后使它android:visibility="gone"
有效地脱离片段布局:
<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="gone"/>
Run Code Online (Sandbox Code Playgroud)
您将把这个进度条放在每个LoadingFragment
子类的布局中,包括fragment_lans.xml
.您可以使用<include>
标签让这里的生活更轻松.
更改,LoadingFragment
以便a)它不会干扰其子类'布局的膨胀,b)它使用子类'活动视图层次结构中的进度条:
public class LoadingFragment extends Fragment {
public void showLoader() {
if (getView() != null) {
View progressBar = getView().findViewById(R.id.progress_bar);
if (progressBar != null) {
progressBar.setVisibility(View.VISIBLE);
}
}
}
public void hideLoader() {
if (getView() != null) {
View progressBar = getView().findViewById(R.id.progress_bar);
if (progressBar != null) {
progressBar.setVisibility(View.GONE);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)现在您应该看到您的期望.
编辑
如果你真的想使用你开始使用的布局方案,这是我的建议:
你的活动正在膨胀main_layout
,有进度条,所以我会给活动一些责任.
现在,您可以为片段编写一些代码,这些代码将遍历视图层次结构并查找进度条.这不是我的偏好.
这是另一种方法:
创建一个界面
interface ProgressDisplay {
public void showProgress();
public void hideProgress();
}
Run Code Online (Sandbox Code Playgroud)让活动实现它
public class MainActivity extends AppCompatActivity implements ProgressDisplay {
Run Code Online (Sandbox Code Playgroud)
...
public void showProgress() {
findViewById(R.id.loading).setVisibility(View.VISIBLE);
}
public void hideProgress() {
findViewById(R.id.loading).setVisibility(View.GONE);
}
Run Code Online (Sandbox Code Playgroud)然后将方法添加到LoadingFragment
调用该活动:
protected void showProgress() {
if (getActivity() instanceof ProgressDisplay) {
((ProgressDisplay) getActivity()).showProgress();
}
}
protected void hideProgress() {
if (getActivity() instanceof ProgressDisplay) {
((ProgressDisplay) getActivity()).hideProgress();
}
}
Run Code Online (Sandbox Code Playgroud)这样,您可以使用进度视图进行任何使布局膨胀的活动,并使其实现,ProgressDisplay
以便您可以使用LoadingFragment
该类.
您也可以创建一个LoadingActivity
类和子类.
归档时间: |
|
查看次数: |
4658 次 |
最近记录: |