玩安卓无框架版本

总结

很喜欢康老师的一句话:懒是会被淘汰的,我最讨厌懒的学生

我自己就很懒 喜欢照抄别人的程序 大一到现在的机房考试没一次不去寻求google帮助的

作者我现在还未学习kotlin用的java

本片文章照写的github作者taolaoge的kotlin版本

GitHub - taolaoge/wanAndroid
写的java版的玩安卓 我自己的java代码还未上传到github 我比较懒 可以加我qq1546795986获取源码

这是写完后的效果

这是主要的架构

群里的大佬都说玩安卓是个最简单的项目 我反正一个人不借助别人的文章肯定现在写不出来

讲一下总体的流程吧:我先写的工具类,就写了一个HttpUtil,用到了okthttp,之前没用过addHeader,也是学到了新东西,然后就是活动,最开始的就是登录和注册,这个相对简单,接着写了登录与注册的ui,然后就是主界面的ui,搭配了一个menu,还有个NavigationView 对我来说还挺新奇的,然后就是适配器了adapter,总觉得断断续续的学习安卓,有时候连最简单的适配器也写不出来啊,我一般就是,先绑定对应的item,得到new ViewHolder(view),然后就是构造函数,一般都是一个context和一个对应的泛型arraylist,紧接着就是找到对应的item里面的控件,在哪里找你肯定知道对吧,这都不知道先去看第一行代码吧,最后就是好多好多的holder.setText啦啦啦,然后就是itemView的点击事件,这里呢,taolaoge还用到了一个我之前不知道的东西SparseBooleanArray,就感觉跟map好像,里面有设置收藏的点击逻辑接着就是写广场的界面了,分成了好多碎片来写,ui啥的我就先不说了,然后就是FirstFragment,ItemFragment,SquareFragment,SystemFragment,WechatFragment,中间还有20个小碎片,这是taolaoge的逻辑,其实我觉得挺好的,因为我想不出比这更好的了,我到写完了都还没理解数据是怎么来的哈哈,我真是个菜狗,我猜主要是在碎片里请求数据,转换格式,将得到的数据放到list里面,然后将适配器放到rv里面,rv自然就吧数据放上去了应该,然后主界面有一个碎片管理器,点到哪里,碎片就到哪里哦

详解+我的学习

依赖来啦

implementation 'de.hdodenhof:circleimageview:3.1.0'
implementation 'com.github.bumptech.glide:glide:4.12.0'
implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
implementation 'io.github.youth5201314:banner:2.2.2'
implementation 'com.google.code.gson:gson:2.8.9'
implementation("com.squareup.okhttp3:okhttp:4.9.3")
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.4.0'·

HttpUtil(就这一个工具类哦)

在kotlin里面貌似是object

java则是

public class HttpUtil {
public void sendOkHttpGetRequest(String address, String cookie, Callback callback){
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(address).addHeader("cookie", cookie).build();
client.newCall(request).enqueue(callback);
}
public void sendOkHttpPostRequest(String address, RequestBody requestBody,String cookie,Callback callback){
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(address).addHeader("Cookie", cookie).post(requestBody).build();
client.newCall(request).enqueue(callback);
}
}
taolaoge真牛 感觉封装的挺棒的,以前没见过这个addHeader("cookie", cookie),估计是请求头吧

后面能得到cookie缓存

语法:

addHeader(String name,String value)

参数说明:

  • name:header 的名称。
  • value:header 的值。

发现没有 这个函数的最后一个参数callback 叫做打回来

调用的时候使用new Callback(){ 逻辑 }

LoginActivity 和 RegisterActivity

这玩意你应该会写吧,不会的话揍你小胸口

<style name="Theme.MyWanandroid" parent="Theme.AppCompat.Light.NoActionBar">

先设置了这个才能使用我们的toolbar

setSupportActionBar(toolbar);

if (getSupportActionBar()!=null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
} 标题栏不为空就 设置一个setDisplayHomeAsUpEnabled 左上角那玩意

先写注册的逻辑

得到三个参数mEdUsername,mEdPassword,mEdRePassword对应的值

创建一个RequsetBody 用的FormBody.Builder()

RequestBody requestBody = new FormBody.Builder()
.add("username",username)
.add("password",password)
.add("repassword",rePassword)
.build();

然后就注册的点击事件

Post方法

new HttpUtil().sendOkHttpPostRequest(
"https://www.wanandroid.com/user/register",
requestBody, "",
new Callback()

在response里面

String responseData = response.body().string();

Gson gson = new Gson();
RegisterResponse registerResponse = gson.fromJson(responseData, RegisterResponse.class);
String message = registerResponse.getErrorMsg();

注:先用postman这个软件调试 或者直接在AS里面打Log.d 接口将得到的json数锯转换为bean类

然后用插件gsonformatplus 转换 就可以得到RegisterResponse 实例化对象了

String message = registerResponse.getErrorMsg();
if (message.equals("")){
startActivity(new Intent(RegisterActivity.this,LoginActivity.class));
finish(); 判空没问题就转到登录界面

也是得到俩个参数的String值,然后

FormBody requestBody = new FormBody.Builder()
.add("username", username)
.add("password", password)
.build();

Get请求

new HttpUtil().sendOkHttpPostRequest(
"https://www.wanandroid.com/user/login",
requestBody,
"",
new Callback()

这个Response里面的就有点难理解了

写了一个迭代器 我到现在还不知道原理

Iterator<Pair<String, String>> iterator = response.headers().iterator();

response.headers().iterator();看图 这玩意是个键值对

这是taolaoge写的 我没学过kotlin 这玩意估计是个匿名表达式

我们用java应该这样写

while (iterator.hasNext()){
Pair<String, String> next = iterator.next();
Log.d(TAG,next.getFirst());
Log.d(TAG,next.getSecond());

if (next.getFirst().equals("Set-Cookie")){
Log.d(TAG,"添加一次");
strBuilder.append(next.getSecond()).append(";");
}

这样就可以把

用iterater.next();可以得到一个Pair键值对

然后就可以得到缓存的 键为Set-Cookie 的值的连接体

设置用户的个人信息,拼接完毕cookie并转为String类型
setMyselfMessMessage(strBuilder.toString(),loginResponse.data.getUsername());

//携带cookie请求发起网络请求
new HttpUtil().sendOkHttpGetRequest(
"https://wanandroid.com//user/lg/userinfo/json",
header,
new Callback() {

这里的header是之前的连接体 传进来主要是用于后面的保存

将请求到的的数据用intent1传到MainActivity 用于视图的修改

setSharePreference(header,username);

重点来了 这个方法里面

//获取spd editor对象

SharedPreferences.Editor editor = getSharedPreferences("cookie", Context.MODE_PRIVATE).edit();

我把它叫做spd 用来存储cookie以便实现后面的自动登录

editor.putString("cookie",cookie);
editor.putString("username",username);
editor.apply();

这个界面就还有个onKeyDown方法 这是重写的

当你返回时 用intent跳到主界面

到这里 Login 和Register 就完结

WebActivity

这个很简答 就是利用intent传入的address 利用webView这个控件打开网页就可

if (getIntent().getStringExtra("address")!=null) {
address = getIntent().getStringExtra("address");
}
WebView webView = (WebView) findViewById(R.id.webview);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient());
webView.getSettings().setDomStorageEnabled(true);
webView.loadUrl(address);
可以看到先时做了一个判空,说到这里,我遇到了好多好多空指针

setJavaScriptEnabled 支持启用javaScript

setDomStorageEnabled正常缓存一些数据 可以保存你看那些东西缓存

loadUrl 这不用说把 加载资源定位标志(俗称网址)

BannerAdapter

这里我是第一次写这个Banner的适配器,总结就是,每个Adapter都会传入一个对象列表,比如这里传入的就是ArrayList<Banner> data,也是用的构造函数传入的,最开始找到item控件

View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.home_vp2_item, parent, false);

然后在ViewHolder找到imageView这个轮播图就一个image就是主页最上面的三张图

然后就是onBindViewHolder

int newPosition = position % 3;//这里我没想懂
Glide.with(holder.itemView.getContext()).load(mData.get(newPosition).getUri()).into(holder.imageView);

下面这个用到了Glide库,第一个参数是context,第二个参数是url,第三个是容器

其余的数据绑定Adapter

接下来的HomeArticleAdapter,ItemArticleAdapter,SquareArticleAdapter,StarArticleAdapter,WechatArticleAdapter属于一个沫子刻出来的,非常像,我这里详细分析一个即可哦

开始都要定义这些变量

private static final String TAG = "ItemArticleAdapter";//打Log用的
private List<Item> articleList = new ArrayList<>();绑定传入的数据然后加载到item上面
private String cookie;缓存
private ItemArticleAdapter.ViewHolder viewHolder;//可写可不写
private ViewGroup parent1;context参数要用
private SparseBooleanArray mCheckBoxStates =new SparseBooleanArray();

这是个新东西

SparseBooleanArray是什么东东呢

就是一个存布尔值的pair(一对哦 男女搭配 干活累累)

然后在onCreateViewHolder 找到这个adapter对应的item,然后将parent1绑定parentView view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_item, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
parent1 = parent;
return viewHolder;

接着干嘛你应该知道把,去ViewHolder找到item里面的控件,就是这样的顺序

设置成局部变量,方便后面holder的调用

现在就是onBindViewHolder绑定视图 这个类名就告诉你要绑定数据了

Item item = articleList.get(position);//先在articleList,我把它叫做对象数组把,它里面每一个item都是一个完整的Item的对象 包含了如下数据
String envelopPic = item.getEnvelopPic();
holder.mTvAuthor.setText(item.getAuthor());
holder.mTvTime.setText(item.getNiceData());
holder.mTvDesc.setText(item.getDesc());
holder.mTvTitle.setText(item.getTitle());

加载图片
Glide.with(holder.itemView.getContext()).load(envelopPic).into(holder.mImg);

这个就不用说了

每个的holder.itemView都有一个点击事件 , 你一点就去WebActivity打开网页了

holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String address = item.getLink();
Log.d(TAG,address);
Intent intent = new Intent(parent1.getContext(), WebActivity.class);
intent.putExtra("address",address);
parent1.getContext().startActivity(intent);
}
});

然后就是收藏的点击处理

int id = item.getId();//得到当前点击对象的id,方便后面的数据请求
//为CheckBox标记位置
holder.mCheckBox.setTag(position);
//为CheckBox注册点击事件
holder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//dangCheckBox被点击时,此时的位置 ,后边会放进mCheckBoxStates
int pos = (Integer)buttonView.getTag();

//先做一个 是否登录的逻辑,注意 == 和.equals()的逻辑是不一样的,前者是地址,后者是值
if (cookie.equals("")){
boolean checked = holder.mCheckBox.isChecked();
checked =false;
Toast.makeText(parent1.getContext(), "请先登录", Toast.LENGTH_SHORT).show();
}else {
if (isChecked){
//如果被选中,则将他的位置添加进SpareseBooleanArray()
//第一个参数为键,第二个参数为添加的Boolean
mCheckBoxStates.put(pos,true);
//dosomething():收藏文章
FormBody requestBody = new FormBody.Builder()
.build();
new HttpUtil().sendOkHttpPostRequest("https://www.wanandroid.com/lg/collect/" + id + "/json"
, requestBody
, cookie
, new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
Log.d(TAG,"onFailure"+ e.toString());
}

@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
//收藏成功后的逻辑,他会自动和后台对接,后面我们请求收藏的逻辑就会返回给我们
}
}
);}else {
//如果没有被选中,则删除键值对
mCheckBoxStates.delete(pos);
//dosomething():取消收藏
FormBody requestBody = new FormBody.Builder()
.build();
new HttpUtil().sendOkHttpPostRequest("https://www.wanandroid.com/lg/collect/" + id + "/json",
requestBody,
cookie,
new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
Log.d(TAG,"onFailure"+ e.toString());
}

@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
//取消收藏成功的逻辑

}
});
}
}
}
});
//adapter加载数据时,这个位置的item取出他的值,如果无,则返回false,即CheckBox不会被选中
//这一步是因为rv的复用可能导致CheckBox也会复用
holder.mCheckBox.setChecked(mCheckBoxStates.get(position,false));
//后端的数据文章是否被收藏,上一行的mCheckBoxStates无法保存到本地,所以加载数据时是否收藏还需请求后端数据
if (item.isCollect()){
boolean checked1 = holder.mCheckBox.isChecked();
checked1 = true;
}
}

这边说一下数据bean类和class类

玩Android 开放API-玩Android - wanandroid.com玩安卓官方api都有这些数据,而且你可以用postman去get和post,然后生成具体的bean类和class类,bean类主要是用来gson解析后的数据处理,class类,用于那些ArrayLIst<class类>的传递

接下里是Fragment

跟Adapter一样大家都是一个沫子刻出来的,会了一个另外一个cv即可,换个接口api和一个类型class

就简绍一下FirstFragment(广场碎片)

public class FirstFragment extends Fragment {
private static final String TAG = "FirstFragment";//打Log用
private RecyclerView.LayoutManager layoutManager1;绑定rv的layoutManager1
private HomeArticleAdapter adapter1;绑定rv的adapter1
private int curPage = 0;
private boolean isLoading = false;
int lastPosition = 498;
private RecyclerView recyclerView;
private ViewPager2 viewPager2;
private ArrayList<com.example.mywanandroid.Banner> listPath = new ArrayList<>();
private ArrayList<String> listTitle;
private ArrayList<Home> homeList= new ArrayList<>();
private View view2;
private Object data;
private Boolean isSliding;

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

//先找到碎片对应的fragment_first
view2 = inflater.inflate(R.layout.fragment_first, container, false);
Log.d(TAG,"我不是空的");

//找到vp2和rv
viewPager2 = view2.findViewById(R.id.home_vp2);
recyclerView = view2.findViewById(R.id.home_rv);
return view2;
}
//每次都要重写这个方法onViewCreated创建视图
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getData();//先看这个
viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override

//监听页面切换事件
public void onPageSelected(int position) {
super.onPageSelected(position);
//监听是否滑动 改变
lastPosition = position;
}
});
initRecycleView();
loadMoreData();
freshRecycleView();
}
public void getData() {//得到banner对应的图片path
new HttpUtil().sendOkHttpGetRequest(
"https://www.wanandroid.com/banner/json", "",
new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
Log.d(TAG,"onFailure" +e.toString());
}

@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
String responseData = response.body().string();
Gson gson = new Gson();
BannerBean bannerResponse = gson.fromJson(responseData, BannerBean.class);

//bannerResponse:得到BannerBean 的这个带有实例化的数据
int i = 0;
while (i<3){
listPath.add(new Banner(bannerResponse.getData().get(i).getImagePath()));

// listPath他也是一个Banner类型的对象List,然后传入3个带有不同uri的对象
i++;
}
if (getActivity()!=null) {
getActivity().runOnUiThread(new Runnable() {

// 跳到主线程更改ui
@Override
public void run() {
Log.d(TAG,listPath.toString());
viewPager2.setAdapter(new BannerAdapter(listPath));

// 传入BannerAdapter的BannerList 的adapter:new BannerAdapter(listPath)
viewPager2.setCurrentItem(498);//当前项目
}
});

}
int j = 0;
while (j<1001){
lastPosition++;
try {
Thread.sleep(50000);
if (getActivity()!=null) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
viewPager2.setCurrentItem(lastPosition);
}
});

}
} catch (InterruptedException e) {
e.printStackTrace();
}

}
}
}
);
}
private void initRecycleView() {// 初始化rv
if (getActivity()!=null) {

//先拿到SharedPreferences 的cookie 后面传入适配器
SharedPreferences pres = getActivity().getSharedPreferences("cookie", Context.MODE_PRIVATE);
String cookie = pres.getString("cookie", "");
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
layoutManager1 = new LinearLayoutManager(getContext());
adapter1 = new HomeArticleAdapter(homeList,cookie);
recyclerView.setLayoutManager(layoutManager1

// 调用addItemDecoration添加自定义分割线第一个参数是rv的context,第二个是vertical
recyclerView.addItemDecoration(new DividerItemDecoration(recyclerView.getContext(),DividerItemDecoration.VERTICAL));
recyclerView.setAdapter(adapter1);
}
});

}
}

private void freshRecycleView() {

// 这玩意我都看不懂
isSliding = false;

//滚动事件OnScrollListener
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
//dx为横向滚动 dy为竖向滚动
//如果为竖向滚动,则isSliding属性为true,横向滚动则为false
if (dy > 0){
isSliding = true;
}
}

@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
//manager必须为LinearLayoutManager
LinearLayoutManager manager = (LinearLayoutManager)recyclerView.getLayoutManager();
//newState是RecycleView的状态 如果它的状态为没有滚动时SCROLL_STATE_IDLE
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
//获取最后一个完全显示的ItemPosition
int lastVisibleItem = manager.findLastCompletelyVisibleItemPosition();
int totalItem = manager.getItemCount();
if (lastVisibleItem == (totalItem -1) && !isLoading){
isLoading = true;
loadMoreData();
}
}
}
});
}

private void loadMoreData() {//获取更多数据

//每次都加一个小碎片
SharedPreferences prefs = getActivity().getSharedPreferences("cookie", Context.MODE_PRIVATE);
String cookie = prefs.getString("cookie", "");

// curPage : 页码,拼接在连接中,从0开始。
new HttpUtil().sendOkHttpGetRequest("https://www.wanandroid.com/article/list/" + curPage + "/json",
cookie, new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
Log.d(TAG,"onFailure" +e.toString());
isLoading = false;
}

@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {

向下滑动

每次都加一个小碎片
curPage +=1;
String responseData = response.body().string();

recyclerViewData(responseData);
isLoading = false;
}
});
}

private void recyclerViewData(String responseData) {

// 得到数据 绑定到构造函数 生成一个新对象Home然后传到homeList里面,然后放到adapter里面的啦
Gson gson = new Gson();
HomeArticleResponse homeArticleResponse = gson.fromJson(responseData, HomeArticleResponse.class);
int size = homeArticleResponse.getData().getDatas().size() -1;
int m = 0;
while (m<=size){
String address = homeArticleResponse.getData().getDatas().get(m).getLink();
String author = homeArticleResponse.getData().getDatas().get(m).getAuthor();
String shareUser = homeArticleResponse.getData().getDatas().get(m).getShareUser();
String title = homeArticleResponse.getData().getDatas().get(m).getTitle();
String superName = homeArticleResponse.getData().getDatas().get(m).getSuperChapterName();
String name = homeArticleResponse.getData().getDatas().get(m).getChapterName();
String niceDate = homeArticleResponse.getData().getDatas().get(m).getNiceDate();
int id = homeArticleResponse.getData().getDatas().get(m).getId();
Boolean collect = homeArticleResponse.getData().getDatas().get(m).getCollect();
if (author.equals("")){
//添加新的Square
homeList.add(new Home(shareUser,
superName,
name,
title,
niceDate,
address, id, collect));
}else {
homeList.add(new Home(author, superName, name, title, niceDate, address, id, collect));
}

m++;
}
//不能重新创建一个adapter这样会使得recycleView自动滚动到顶部,而应该使用原来的adapter
freshRecycleViewData();
}

private void freshRecycleViewData() {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {

//notifyDataSetChanged方法通过一个外部的方法控制如果适配器的内容改变时需要强制调用getView来刷新每个Item的内容,可以实现动态的刷新列表的功能。
recyclerView.getAdapter().notifyDataSetChanged();
}
});
}
}

微信公众号和项目

都分开有14个碎片 只需要换一下api即可获得数据

ItemFragment 和 WechatFragment

private void initViewPager() {
ViewPager2 viewPager = view1.findViewById(R.id.item_viewPager2);
TabLayout tabLayout = view1.findViewById(R.id.item_tabLayout);
ArrayList<Fragment> fragments = new ArrayList<>();
fragments.add(new Fragment1());
fragments.add(new Fragment2());
fragments.add(new Fragment3());
fragments.add(new Fragment4());
fragments.add(new Fragment5());
fragments.add(new Fragment6());
fragments.add(new Fragment7());
fragments.add(new Fragment8());
fragments.add(new Fragment9());
fragments.add(new Fragment10());
fragments.add(new Fragment11());
fragments.add(new Fragment12());
fragments.add(new Fragment13());
fragments.add(new Fragment14());
ArrayList<String> data = new ArrayList<>();
data.add("完整项目");
data.add("跨平台应用");
data.add("资源聚合类");
data.add("动画");
data.add("RV列表动效");
data.add("项目基础功能");
data.add("网络&文件下载");
data.add("TextView");
data.add("键盘");
data.add("快应用");
data.add("日历&时钟");
data.add("K线图");
data.add("硬件相关");
data.add("表格类");
WechatFragmentAdapter adapter = new WechatFragmentAdapter(ItemFragment.this, fragments);
viewPager.setAdapter(adapter);
new TabLayoutMediator(tabLayout, viewPager, true, true, new TabLayoutMediator.TabConfigurationStrategy() {
@Override
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
tab.setText(data.get(position));
}
}).attach();
}

private void initViewPager() {
ViewPager2 viewPager = view1.findViewById(R.id.wechat_viewpager2);
TabLayout tabLayout = view1.findViewById(R.id.wechat_tabLayout);
ArrayList<Fragment> fragments = new ArrayList<>();
fragments.add(new Fragment1());
fragments.add(new Fragment2());
fragments.add(new Fragment3());
fragments.add(new Fragment4());
fragments.add(new Fragment5());
fragments.add(new Fragment6());
fragments.add(new Fragment7());
fragments.add(new Fragment8());
fragments.add(new Fragment9());
fragments.add(new Fragment10());
fragments.add(new Fragment11());
fragments.add(new Fragment12());
fragments.add(new Fragment13());
fragments.add(new Fragment14());
ArrayList<String> data = new ArrayList<>();
data.add("鸿洋");
data.add("郭霖");
data.add("玉刚说");
data.add("承香墨影");
data.add("Android群英传");
data.add("code小生");
data.add("谷歌开发者");
data.add("奇卓社");
data.add("美团技术团队");
data.add("GcsSloop");
data.add("互联网侦察");
data.add("susion随心");
data.add("程序亦非猿");
data.add("Gityuan");
WechatFragmentAdapter adapter = new WechatFragmentAdapter(WechatFragment.this, fragments);
viewPager.setAdapter(adapter);
new TabLayoutMediator(tabLayout, viewPager, true, true, new TabLayoutMediator.TabConfigurationStrategy() {
@Override
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
tab.setText(data.get(position));
}
}).attach();
}

MainActivity

实现自动登录逻辑

private void initLogin() {
SharedPreferences pres = getSharedPreferences("cookie", Context.MODE_PRIVATE);
String cookie = pres.getString("cookie", "") != null ? pres.getString("cookie", "") : "";
Log.d(TAG,cookie);
new HttpUtil().sendOkHttpGetRequest(
"https://wanandroid.com//user/lg/userinfo/json",
cookie, new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
Log.d(TAG, e.toString());
}

@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
String responseData = response.body().string();
Gson gson = new Gson();
MyselfResponse myselfResponse = gson.fromJson(responseData, MyselfResponse.class);
String errorMsg = myselfResponse.getErrorMsg();
if (errorMsg.equals("")) {
Integer level = myselfResponse.getData().getCoinInfo().getLevel();
String rank = myselfResponse.getData().getCoinInfo().getRank();
runOnUiThread(new Runnable() {
@Override
public void run() {
SharedPreferences pres = getSharedPreferences("cookie", Context.MODE_PRIVATE);
String usernamr = pres.getString("usernamr", "");
mTvLevel.setText("登记:" + level);
mTvRank.setText("排名:" + rank);
mTvUsername.setText(usernamr);
}
});
}
}
}
);

碎片管理逻辑:

private void setFragmentPosition(int position) {

//getSupportFragmentManager专门用来管理碎片
FragmentManager supportFragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = supportFragmentManager.beginTransaction();
Fragment currentFragment = fragments.get(position);
Fragment lastFragment = fragments.get(lastIndex);
lastIndex = position;
// //隐藏上一个fragment
transaction.hide(lastFragment);
//如果这个currentFragment没有被添加进去,则开一个新的transaction先移除这个Fragment
//再原来的transaction内加入这个fragment

if (!currentFragment.isAdded()) {
supportFragmentManager.beginTransaction().remove(currentFragment).commit();
//将currentFragment添加到我们的一个占位的容器内
//第一个参数为容器,第二个参数为我们想要添加的fragment

transaction.add(R.id.lin_lay_fragment, currentFragment);
}
transaction.show(currentFragment);
transaction.commit();
}

然后就差不多了 今天就写这么多

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值