本文使用了livedata、viewmodel、glide4.0以上版本,封装了BaseActivity、BaseFragment、BaseHolder、BaseAdapter(还有简单的BaseApplication),感觉也是棒棒的呢,当然本人还是一个实习小菜鸟,如有写的不对的地方请多多指教,也可以交流一下怎么学习啦!!!
看一下效果
导入依赖
implementation 'com.android.support:support-v4:28.0.0'
implementation 'com.android.support:design:28.0.0'
//Butterknife
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
//ViewModel livedata
implementation 'android.arch.lifecycle:extensions:1.1.0'
annotationProcessor "android.arch.lifecycle:compiler:1.1.0"
//Glide 4.6
implementation 'com.github.bumptech.glide:glide:4.6.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.6.1'
implementation 'com.github.bumptech.glide:okhttp3-integration:4.6.1'
//Retrofit2
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
那么下面就开始走起,我们的代码之路,向着码农前进,哈哈(*๓´╰╯`๓)♡
先从封装开始介绍:
BaseAcitvity
package com.example.asus.detailsnew.base;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.example.asus.detailsnew.R;
import butterknife.ButterKnife;
import butterknife.Unbinder;
/**
* Created by asus on 2019/1/7.
*/
public abstract class BaseActivity extends AppCompatActivity {
private Context context;
private Unbinder unbinder;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(ininLayout());
context = this;
unbinder = ButterKnife.bind(this);
initView();
}
public Context getContext() {
return context;
}
protected abstract int ininLayout();
protected abstract void initView();
public void initToolbar(Toolbar toolbar, TextView textView, String title,boolean isBack) {
if (textView != null && title != null) {
textView.setText(title);
}
if (toolbar != null) {
toolbar.setTitle("");
if (isBack) {
toolbar.setNavigationIcon(R.drawable.ic_left);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
}
}
public void ShowToast(String msg) {
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
}
public void startActivity(Activity activity, Class extends Activity> cls) {
Intent intent = new Intent();
intent.setClass(activity, cls);
startActivity(intent);
overridePendingTransition(R.animator.up_in,R.animator.up_out);
}
public void startActivity(Activity activity, Class extends Activity> cls, Bundle bundle) {
if (activity != null && cls != null && bundle != null) {
Intent intent = new Intent();
intent.putExtras(bundle);
intent.setClass(activity, cls);
startActivity(intent);
overridePendingTransition(R.animator.up_in,R.animator.up_out);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unbinder.unbind();
}
@Override
public void finish() {
super.finish();
overridePendingTransition(R.animator.down_in,R.animator.down_out);
}
}
还有BaseFragment的封装,不过也很相似啦,篇幅有限,先介绍BaseAdapter啦٩(๑^o^๑)۶
BaseHolder
package com.example.asus.detailsnew.base;
import android.graphics.Bitmap;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.asus.detailsnew.utils.GlideApp;
/**
* Created by asus on 2019/1/14.
*/
public class BaseHolder extends RecyclerView.ViewHolder {
private View itemView;
private SparseArray views;
public BaseHolder(@NonNull View itemView) {
super(itemView);
this.itemView = itemView;
views = new SparseArray<>();
}
public View getItemView() {
return itemView;
}
public View getViewId(int viewId) {
View view = views.get(viewId);
if (view == null) {
view = itemView.findViewById(viewId);
views.put(viewId, view); // 控件id的int类型 控件view
}
return (T) view;
}
public static T getHolder(int layoutId, ViewGroup parent) {
return (T) new BaseHolder(LayoutInflater.from(BaseApplication.getmContext()).inflate(layoutId, parent, false));
}
public BaseHolder setOnClickListener(int viewId, View.OnClickListener onClickListener) {
getViewId(viewId).setOnClickListener(onClickListener);
return this;
}
public BaseHolder setText(int viewId, String msg) {
((TextView) getViewId(viewId)).setText(msg);
return this;
}
public BaseHolder setText(int viewId, int resId) {
((TextView) getViewId(viewId)).setText(resId);
return this;
}
public BaseHolder setImageView(int ImageViewId, String url) {
GlideApp.with(BaseApplication.getmContext()).load(url).into((ImageView) getViewId(ImageViewId));
return this;
}
public BaseHolder setImageView(int imagViewId, int resId) {
((ImageView) getViewId(imagViewId)).setImageResource(resId);
return this;
}
public BaseHolder setImageView(int imagViewId, Bitmap bitmap) {
((ImageView) getViewId(imagViewId)).setImageBitmap(bitmap);
return this;
}
}
这里面要讲一下Glide4.0以后如何使用GlideApp(*๓´╰╯`๓)♡,一般情况下是找不到GlideApp的,可能是我太可爱惹,被我发现了GlideApp,O(∩_∩)O有点扯淡,介绍一下在4.0以后是要介这样子操作一下
哦,不别打人,是这样子操作一下(≧ω≦)/
package com.example.asus.detailsnew.utils;
import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.module.AppGlideModule;
/**
* Created by asus on 2019/1/14.
*/
@GlideModule
public class GlideConfig extends AppGlideModule {
//禁止解析Manifest
@Override
public boolean isManifestParsingEnabled() {
return false;
}
}
然后Build->Rebuild Project 就可以找到GlideApp了٩(๑^o^๑)۶
有点扯远了,这下子介绍了BaseHolder,真的下面就讲 BaseAdapter
package com.example.asus.detailsnew.base;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;
import java.util.List;
/**
* Created by asus on 2019/1/14.
*/
public abstract class BaseAdapter extends RecyclerView.Adapter {
private List datas;
private int [] layoutIds;
//多种item
public BaseAdapter(List datas, int[] layoutIds) {
this.datas = datas;
this.layoutIds = layoutIds;
}
//单个item
public BaseAdapter(List datas,int layoutId){
this.datas=datas;
this.layoutIds=new int[]{layoutId};
}
@NonNull
@Override
public BaseHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
return BaseHolder.getHolder(layoutIds[i],viewGroup);
}
@Override
public void onBindViewHolder(@NonNull BaseHolder holder, int position) {
onBinDatas(holder,datas.get(position),position);
}
protected abstract void onBinDatas(BaseHolder holder, T t, int position);
@Override
public int getItemCount() {
return datas==null?0:datas.size();
}
}
还有BaseAdapter的具体实现子类ヾ(@^▽^@)ノ
package com.example.asus.detailsnew.adapter;
import com.example.asus.detailsnew.base.BaseAdapter;
import com.example.asus.detailsnew.base.BaseHolder;
import java.util.List;
/**
* Created by asus on 2019/1/14.
*/
public abstract class MutiLayoutAdapter extends BaseAdapter {
public MutiLayoutAdapter(List datas, int[] layoutIds) {
super(datas, layoutIds);
}
@Override
public int getItemViewType(int position) {
return getItemType(position);
}
protected abstract int getItemType(int position); //区分多个item的
@Override
protected void onBinDatas(BaseHolder holder, T t, int position) {
onBind(holder,t,position,getItemType(position));
}
protected abstract void onBind(BaseHolder holder, T t, int position,int itemType);
}
下面在讲一下ViewModel
package com.example.asus.detailsnew.http.model;
import android.arch.lifecycle.MutableLiveData;
import android.arch.lifecycle.ViewModel;
import android.util.Log;
import com.example.asus.detailsnew.http.manager.HttpManager;
import com.example.asus.detailsnew.http.manager.NewsApi;
import com.example.asus.detailsnew.ui.bean.DataBean;
import com.example.asus.detailsnew.ui.bean.Result;
import com.example.asus.detailsnew.ui.bean.ResultBean;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Created by asus on 2019/1/14.
*/
public class DataViewModel extends ViewModel {
MutableLiveData> liveData = new MutableLiveData<>();
HttpManager manager = new HttpManager();
NewsApi api = manager.getRetrofit().create(NewsApi.class);
public MutableLiveData> getLiveData(String type) {
api.getNews(type, "bc0a3a53be1e97115c2313e638662cae").enqueue(new Callback>>() {
@Override
public void onResponse(Call>> call, Response>> response) {
if (response != null) {
liveData.setValue(response.body().getResult().getData());
// Log.i("是否有数据",response.body().getData().size()+"");
}
}
@Override
public void onFailure(Call>> call, Throwable t) {
}
});
return liveData;
}
}
以及最终的Activity与Fragment使用
package com.example.asus.detailsnew.ui.activity;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.widget.TextView;
import com.example.asus.detailsnew.R;
import com.example.asus.detailsnew.base.BaseActivity;
import com.example.asus.detailsnew.ui.fragment.NewsFragment;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
public class MainActivity extends BaseActivity {
@BindView(R.id.title)
TextView mTitle;
@BindView(R.id.toolbar)
Toolbar mToolbar;
@BindView(R.id.tab_layout)
TabLayout mTabLayout;
@BindView(R.id.view_Pager)
ViewPager mViewPager;
private String[] mTitles = {"头条", "社会", "国内", "国际", "娱乐"};
List fragmentList = new ArrayList<>();
@Override
protected int ininLayout() {
return R.layout.activity_main;
}
@Override
protected void initView() {
initToolbar(mToolbar, mTitle, "哈哈新闻", false);
for (int i = 0; i < mTitles.length; i++) {
fragmentList.add(NewsFragment.newInstance(i));
}
mViewPager.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager()) {
@Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
@Override
public int getCount() {
return fragmentList.size();
}
public CharSequence getPageTitle(int position) {
return mTitles[position];
}
});
mTabLayout.setupWithViewPager(mViewPager);
}
}
package com.example.asus.detailsnew.ui.fragment;
import android.arch.lifecycle.MutableLiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.asus.detailsnew.R;
import com.example.asus.detailsnew.adapter.MutiLayoutAdapter;
import com.example.asus.detailsnew.base.BaseApplication;
import com.example.asus.detailsnew.base.BaseFragment;
import com.example.asus.detailsnew.base.BaseHolder;
import com.example.asus.detailsnew.http.model.DataViewModel;
import com.example.asus.detailsnew.ui.bean.DataBean;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
/**
* A simple {@link Fragment} subclass.
*/
public class NewsFragment extends BaseFragment {
public int position;
@BindView(R.id.recycler)
RecyclerView mRecycler;
DataViewModel viewModel;
List dataBeansList = new ArrayList<>();
public static String[] Type = {"top", "shehui", "guonei", "guoji", "yule"};
public static Fragment newInstance(int position) {
NewsFragment fragment = new NewsFragment();
Bundle bundle = new Bundle();
bundle.putInt("position", position);
fragment.setArguments(bundle); //setAraguments 传递一个bundler对象
return fragment;
}
@Override
protected void initData() {
position = getArguments().getInt("position");
//双向绑定
viewModel = ViewModelProviders.of(this).get(DataViewModel.class);
viewModel.getLiveData(Type[position]).observe(this, new Observer>() {
@Override
public void onChanged(@Nullable List dataBeans) {
if (dataBeans!=null){
for (int i=0;i adapter=new MutiLayoutAdapter(dataBeansList,new int[]{R.layout.item_layout,R.layout.item}) {
@Override
protected int getItemType(int position) {
Log.i("position",position+"");
if (dataBeansList.get(position).getThumbnail_pic_s02()!=null&&dataBeansList.get(position).getThumbnail_pic_s03()!=null){
return 0;
}else if (dataBeansList.get(position).getThumbnail_pic_s()!=null){
return 1;
}
return 0;
}
@Override
protected void onBind(BaseHolder holder, DataBean dataBean, int position, int itemType) {
if (itemType==0){
holder.setText(R.id.title, dataBean.getTitle());
holder.setImageView(R.id.image_left, dataBean.getThumbnail_pic_s());
holder.setImageView(R.id.image_center, dataBean.getThumbnail_pic_s02());
holder.setImageView(R.id.image_right, dataBean.getThumbnail_pic_s03());
holder.setText(R.id.tv_time, dataBean.getDate());
holder.setText(R.id.tv_type, dataBean.getCategory());
} else if (itemType == 1) {
holder.setText(R.id.tv_title, dataBean.getTitle());
holder.setText(R.id.tv_time, dataBean.getDate());
holder.setText(R.id.tv_type, dataBean.getCategory());
holder.setImageView(R.id.image, dataBean.getThumbnail_pic_s());
}
//可以传一个dataBean.getUrl(),给下一个界面用webView实现浏览
holder.getItemView().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
}
};
mRecycler.setLayoutManager(new LinearLayoutManager(BaseApplication.getmContext(),LinearLayoutManager.VERTICAL,false));
mRecycler.setAdapter(adapter);
}
@Override
protected int initView() {
return R.layout.fragment_news;
}
}
这样子就实现了简单的封装体验惹(≧ω≦)/,当然还是可以进行升级改造的,比如RecyclerView在封装一下下拉刷新和上拉加载,viewmodel和livedata的使用老实讲还是有点头痛啊,感觉还是先把Rxjava全家桶学了比较好,因为这方面的博客多而且使用还广泛,不像viewmodel和Livedata大多数博客都是介绍什么所谓的原理而且还是高度相市的那种,看着都头晕根本不适合实习生学习惹。
数据来源:用的是聚合新闻
demo下载(*๓´╰╯`๓)♡