需求
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布局可以暂时什么都不用放。