1.由上篇文章可实现全页面的加载页面过程。 2.但是我看了下斗鱼APP应该也是网络加载数据的,所以关了网络去这个界面。 发现,有一些默认的布局还是存在的,而不是像上篇文章一样那么的粗暴。直接把整个布局先变成加载的布局 3.所以在保证本身布局的存在下去,用一个加载布局出来。思路就是用自定义控件
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内进行调用 mLoadingFramelayout = new LoadingFramelayout(this); 注意,这里有坑 当我使用构造函数去找对象的时,后面用对象的方法时,UI实现无效,会报空对象。 so,现在使用 mLoadingFramelayout=findViewById(R.id.LoadingFramelayout); 这个是OK的,可以调用里面的方法修改UI 至于为什么。。。我也不是很清楚,不知道有没有大神能告诉一声。 两个都是有对象的。 初步判断可能两者对象不同,所以实现不同。 好了最重要的代码时刻来了。
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 = findViewById(R.id.LoadingFramelayout); 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.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".NetWorkActivity" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="62dp" android:gravity="center" android:orientation="vertical"> <TextView android:id="@+id/text_xx" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="dasfasdfasdfasdfasdf" /> </LinearLayout> <com.example.project_httprequest_study.LoadingFramelayout android:id="@+id/LoadingFramelayout" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:layout_gravity="center"/> </LinearLayout>不同的方法去实现不同的功能,还是比较有趣的,多去探索,多去写,才能学到更多的东西~各位加油。
参考资料 https://www.jianshu.com/p/306d1748d992