Android网络请求失败的加载页面(全页面)

    技术2022-07-16  70

    Android网络请求加载页面

    需求问题分析解决方法

    需求

    1.页面由网络请求数据,得到对应的数据初始化。 2.考虑网络请求需要时间,所以需要加载页面,若加载不成功则多一个按钮重新加载初始化。

    问题分析

    1.要有加载动画 2.线程解决UI变化问题。(/用Hander也可以)

    解决方法

    1.实现加载页面,继承LinearLayout

    public class LoadingFramelayout extends LinearLayout { String TAG = "LoadingFramelayout"; private ImageView mIvLoading; private Button mBtnReTry; private TextView mTextLoading; private RelativeLayout mLoadingView; private AnimationDrawable mAnimationDrawable; private LoadingFramelayout mLoadingFramelayout; private OnFragmentInteractionListener mOnFragmentInteractionListener; private OnFragmentInteractionListener mListener; public LoadingFramelayout(Context context) { super(context); LayoutInflater mInflater = LayoutInflater.from(context); //mInflater.inflate(res,this); View rootView = mInflater.inflate(R.layout.fragment_loading_framelayout,this);//该布局的外部再嵌套一层父布局 mLoadingView = rootView.findViewById(R.id.load_view); mIvLoading = (ImageView) rootView.findViewById(R.id.iv_loading); mBtnReTry = (Button) rootView.findViewById(R.id.iv_btn_retry); mTextLoading = rootView.findViewById(R.id.iv_LoadingText); mBtnReTry.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mOnFragmentInteractionListener.onReload(); } }); init(context); } public LoadingFramelayout(Context context, AttributeSet attrs) { super(context, attrs); LayoutInflater mInflater = LayoutInflater.from(context); //mInflater.inflate(res,this); View rootView = mInflater.inflate(R.layout.fragment_loading_framelayout,this);//该布局的外部再嵌套一层父布局 mLoadingView = rootView.findViewById(R.id.load_view); mIvLoading = (ImageView) rootView.findViewById(R.id.iv_loading); mBtnReTry = (Button) rootView.findViewById(R.id.iv_btn_retry); mTextLoading = rootView.findViewById(R.id.iv_LoadingText); mBtnReTry.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mOnFragmentInteractionListener.onReload(); } }); init(context); } public LoadingFramelayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); LayoutInflater mInflater = LayoutInflater.from(context); //mInflater.inflate(res,this); View rootView = mInflater.inflate(R.layout.fragment_loading_framelayout,this);//该布局的外部再嵌套一层父布局 mLoadingView = rootView.findViewById(R.id.load_view); mIvLoading = (ImageView) rootView.findViewById(R.id.iv_loading); mBtnReTry = (Button) rootView.findViewById(R.id.iv_btn_retry); mTextLoading = rootView.findViewById(R.id.iv_LoadingText); mBtnReTry.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mOnFragmentInteractionListener.onReload(); } }); init(context); } public LoadingFramelayout(Context context, @LayoutRes int res) { // Required empty public constructor super(context); LayoutInflater mInflater = LayoutInflater.from(context); //mInflater.inflate(res,this); View rootView = mInflater.inflate(R.layout.fragment_loading_framelayout,this);//该布局的外部再嵌套一层父布局 mLoadingView = rootView.findViewById(R.id.load_view); mIvLoading = (ImageView) rootView.findViewById(R.id.iv_loading); mBtnReTry = (Button) rootView.findViewById(R.id.iv_btn_retry); mTextLoading = rootView.findViewById(R.id.iv_LoadingText); mBtnReTry.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mOnFragmentInteractionListener.onReload(); } }); init(context); } public LoadingFramelayout(Context context,View view) { super(context); addView(view); LayoutInflater mInflater = LayoutInflater.from(context); View rootView = mInflater.inflate(R.layout.fragment_loading_framelayout,this); mLoadingView = rootView.findViewById(R.id.load_view); mIvLoading = (ImageView) rootView.findViewById(R.id.iv_loading); mBtnReTry = (Button) rootView.findViewById(R.id.iv_btn_retry); mBtnReTry.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { mOnFragmentInteractionListener.onReload(); } }); init(context); } private void init(Context context) { mAnimationDrawable = new AnimationDrawable(); mAnimationDrawable.setOneShot(false); mAnimationDrawable.addFrame(ContextCompat.getDrawable(context,R.drawable.loading_01),500); mAnimationDrawable.addFrame(ContextCompat.getDrawable(context,R.drawable.loading_02),500); mAnimationDrawable.addFrame(ContextCompat.getDrawable(context,R.drawable.loading_03),500); mAnimationDrawable.addFrame(ContextCompat.getDrawable(context,R.drawable.loading_04),500); mAnimationDrawable.addFrame(ContextCompat.getDrawable(context,R.drawable.loading_05),500); mAnimationDrawable.addFrame(ContextCompat.getDrawable(context,R.drawable.loading_06),500); mAnimationDrawable.addFrame(ContextCompat.getDrawable(context,R.drawable.loading_07),500); mAnimationDrawable.addFrame(ContextCompat.getDrawable(context,R.drawable.loading_08),500); mAnimationDrawable.addFrame(ContextCompat.getDrawable(context,R.drawable.loading_09),500); mIvLoading.setImageDrawable(mAnimationDrawable); Log.d(TAG, "走到"); mIvLoading.post(new Runnable() { @Override public void run() { mAnimationDrawable.start(); Log.d(TAG, "走到线程内"); } }); } //这一个用于完成加载的调用方法 public void completeLoading(){ stopLoading(); post(new Runnable() { @Override public void run() { mLoadingView.setVisibility(GONE);//加载完成后,隐藏整个布局 } }); } //成功和失败后停着加载,将动画stop public void stopLoading() { Log.d(TAG, "stopLoading"); ((AnimationDrawable) mIvLoading.getDrawable()).stop(); } //在加载失败后,点击加载再次加载的时候调用 public void startLoading(){ post(new Runnable() { @Override public void run() { mBtnReTry.setVisibility(GONE); mTextLoading.setText(R.string.loading); mIvLoading.setImageDrawable(mAnimationDrawable); ((AnimationDrawable)mIvLoading.getDrawable()).start(); } }); } //加载失败后,停着动画,将失败页面和重新加载按钮Visible出来 public void loadingFailed(){ stopLoading(); post(new Runnable() { @Override public void run() { mIvLoading.setImageResource(R.drawable.loading_fail); mBtnReTry.setVisibility(VISIBLE); mTextLoading.setText(R.string.load_fail); } }); } public void setOnReloadListener(OnFragmentInteractionListener onReloadListener) { mOnFragmentInteractionListener = onReloadListener; } /** * This interface must be implemented by activities that contain this * fragment to allow an interaction in this fragment to be communicated * to the activity and potentially other fragments contained in that * activity. * <p> * See the Android Training lesson <a href= * "http://developer.android.com/training/basics/fragments/communicating.html" * >Communicating with Other Fragments</a> for more information. */ //实现接口,重新加载用作回调 public interface OnFragmentInteractionListener { // TODO: Update argument type and name void onFragmentInteraction(Uri uri); void onReload(); } }

    2.Activity内进行调用

    setContentView(mLoadingFramelayout); //注意这一句

    将指定的资源xml文件加载到对应的activity中,此时,这一句就会替换掉所有的原本,R.id.NetWorkActivity的布局。所以这个加载页面是比较粗暴简单的。而加载完后,如果想显示原本的布局。则在 mLoadingFramelayout.completeLoading(); 后边加上setContentView(R.layout.activity_net_work); 替换掉加载的布局

    public class NetWorkActivity extends AppCompatActivity { private String TAG = "NetWorkActivity"; private LoadingFramelayout mLoadingFramelayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_net_work); mLoadingFramelayout = new LoadingFramelayout(this); //将指定的资源xml文件加载到对应的activity中 setContentView(mLoadingFramelayout); init(); } private void init() { simulation2NetworkFialed(); } //模拟网络加载失败 private void simulation2NetworkFialed(){ //开启一个子线程 new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(2000);//这里我们模拟网络请求休眠2s mLoadingFramelayout.loadingFailed(); mLoadingFramelayout.setOnReloadListener(new LoadingFramelayout.OnFragmentInteractionListener() { @Override public void onFragmentInteraction(Uri uri) { } @Override public void onReload() { mLoadingFramelayout.startLoading(); simulation2Network(); } }); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } //网络请求通畅 private void simulation2Network(){ //开启一个子线程 new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(2000); //这里模拟再次请求网络 mLoadingFramelayout.completeLoading(); //setContentView(R.layout.activity_net_work); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } }

    Fragment_loading_frame.xml

    <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/load_view" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".LoadingFramelayout"> <!-- TODO: Update blank fragment layout --> <TextView android:id="@+id/iv_LoadingText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/loading" android:layout_centerInParent="true" android:layout_above="@id/iv_loading"/> <ImageView android:id="@+id/iv_loading" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/loading_01" android:layout_centerInParent="true" /> <Button android:id="@+id/iv_btn_retry" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="重载" android:layout_below="@id/iv_loading" android:layout_centerInParent="true" android:visibility="gone"/> </RelativeLayout>

    Activity布局可以暂时什么都不用放。

    参考资料 https://www.jianshu.com/p/306d1748d992

    Processed: 0.009, SQL: 9