问题分析
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>
不同的方法去实现不同的功能,还是比较有趣的,多去探索,多去写,才能学到更多的东西~各位加油。