我正在使用android片段在我的应用程序中加载代码。为了创建一个简单的加载程序,我使用了LoadingFragment extends Fragment,然后我的片段类扩展了它,例如:MyFragment extends LoadingFragment
LoadingFragment具有hideLoadershowLoader,理论上我的子类片段应该能够调用onCreateViewonPostExecute来显示和隐藏加载之间的进度条。
布局方面,我有一个main_layout.xml有一个动态片段的framelayout和一个包含进度条的静态relativelayout。
目前,我的片段从一个元素中加载并替换另一个元素,但我已经删除了该代码。
问题
问题是setVisibilty中的LoadingFragment在从子类调用时似乎没有任何效果,例如MyFragment,这是为什么?
我给了LoadingFragment它自己的View变量,我认为应该引用viewMaster但是可见性的改变似乎仍然没有效果?
主要活动

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

}

主布局.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>

最佳答案

问题是setVisibility中的LoadingFragment在从子类调用时似乎没有任何效果,例如MyFragment,这是为什么?
让我们看看当调用MyFragment onCreateView时会发生什么:
您可以调用superonCreateView中的LoadingFragmentmain_layout。这将充气MyFragment并返回充气视图。请注意,此视图未在View mainLayout = super.onCreateView(inflater, container, savedInstanceState);中引用(即loading
您只需将具有LoadingFragment视图组的视图放大,然后将其丢弃。但是,您确实在R.layout.fragment_lans超类中保存了对该视图的引用。
接下来充气LoadingFragment并(在开始加载之后)将该视图作为要在片段中使用的视图返回。
这里要注意的是setVisibility现在引用了一个在片段的活动视图层次结构中没有的视图。
鉴于此,难怪ProgressBar什么都不做,因为片段没有显示该视图。
我不会用继承来做这件事,但如果你一定要用它,这里是如何解决你的问题。
我们只使用RelativeLayout而不使用视图组包装器。既然它在一个android:visibility="gone"中,让我们把它居中。然后让它LoadingFragment这样它就有效地脱离了片段布局:

        <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"/>

您将把这个进度条放在每个fragment_lans.xml子类的布局中,包括<include>。您可以使用LoadingFragment标记来简化这里的生活。
更改main_layout以便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);
           }
        }
    }
}

现在你应该明白你的期望了。
编辑
如果你真的想使用你开始使用的布局方案,这里是我的建议:
你的活动正在膨胀,这有进度条,所以我会给这个活动一些责任。
现在,您可以为片段编写一些代码,这些代码将在视图层次结构中搜索并查找进度条。那不是我的喜好。
下面是另一种方法:
创建接口
interface ProgressDisplay {

    public void showProgress();

    public void hideProgress();
}

使活动实现它
    public class MainActivity extends AppCompatActivity implements ProgressDisplay {


    public void showProgress() {
        findViewById(R.id.loading).setVisibility(View.VISIBLE);
    }

    public void hideProgress() {
        findViewById(R.id.loading).setVisibility(View.GONE);
    }

然后将调用活动的方法添加到LoadingFragment
    protected void showProgress() {
        if (getActivity() instanceof ProgressDisplay) {
            ((ProgressDisplay) getActivity()).showProgress();
        }
    }

    protected void hideProgress() {
        if (getActivity() instanceof ProgressDisplay) {
            ((ProgressDisplay) getActivity()).hideProgress();
        }
    }

这样,您就可以通过progress视图进行任何扩展布局的活动,并让它实现ProgressDisplay,这样就可以使用LoadingFragment类。
您还可以创建一个LoadingActivity类和子类。

07-28 04:11