1.写界面
很明显,这个主界面采用了ViewPager和TabLayout实现界面滑动切换,在使用TabLayout之前记得导包,TabLayout需要导入的包。
2.写Activity
登录后的主页面
* 前提:TabLayout依赖的design包
* 属性:①TabLayout、ViewPager
* 操作: 1.初始化一个适配器类
* 1. 定义标题和页面列表
* 2. 把三个Fragment添加到列表中
* 3. 用列表和标题创建适配器
* 2. 进行关联操作
* 1. ViewPager添加适配器
* 2. TabLayout与ViewPager关联
package com.example.tablayoutmenu;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.List;
/**
* 登录后的主页面
* 前提:TabLayout依赖的design包
* 属性:①TabLayout、ViewPager
* 操作: 1.初始化一个适配器类
* 1. 定义标题和页面列表
* 2. 把三个Fragment添加到列表中
* 3. 用列表和标题创建适配器
* 2. 进行关联操作
* 1. ViewPager添加适配器
* 2. TabLayout与ViewPager关联
*
* @author thinkdoor
*/
public class MainActivity extends AppCompatActivity {
/*
定义UI组件
*/
private TabLayout tabLayout;
private ViewPager viewPager;
/**
* 创建的回调方法
*
* @param savedInstanceState
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化界面组件
tabLayout = (TabLayout) findViewById(R.id.tab_layout);
viewPager = (ViewPager) findViewById(R.id.view_pager);
//获取初始化的适配器
MyFragmentPagerAdapter myFragmentPagerAdapter = init();
//添加适配器
viewPager.setAdapter(myFragmentPagerAdapter);
//设置tablayou和viewpage关联
tabLayout.setupWithViewPager(viewPager);
}
/**
* 初始化适配器
*
* @return:初始化后的适配器
*/
public MyFragmentPagerAdapter init() {
//菜单标题
String[] title = {"新闻", "音乐", "电影"};
//创建装载Fragment的列表
List fragmentlist;
/*
初始化列表,并把创建的三个Fragment页面添加到列表中
*/
fragmentlist = new ArrayList<>();
fragmentlist.add(new FragmentOne());
fragmentlist.add(new FragmentTwo());
fragmentlist.add(new FragmentThree());
//创建Fragment适配器
MyFragmentPagerAdapter myFragmentPagerAdapter;
//适配器进行适配,传入列表与标题
myFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(),
fragmentlist, title);
return myFragmentPagerAdapter;
}
}
3.前面提到了FragmentOne,FragmentTwo,FragmentThree直接创建先放着,记得继承Fragment奥。
4.创建适配器MyFragmentPagerAdpter
fragment的适配器类
* 1.集成FragmentPagerAdapter,实现相关方法
* 2.创建需要显示的List集合
* 3.重写getPageTitle设置标题
package com.example.tablayoutmenu;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import java.util.List;
/**
* fragment的适配器类
* 1.集成FragmentPagerAdapter,实现相关方法
* 2.创建需要显示的List集合
* 3.重写getPageTitle设置标题
*
* @author thinkdoor
*/
public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
//装载fragment的列表
private List list;
//标题
private String[] title;
/**
* 构造方法
*
* @param fm
* @param list:装载fragment的列表
* @param title:标题栏
*/
public MyFragmentPagerAdapter(FragmentManager fm, List list, String[] title) {
super(fm);
this.list = list;
this.title = title;
}
/**
* 返回当前位置的fragment
*
* @param position:当前页面的位置
* @return
*/
@Override
public Fragment getItem(int position) {
return list.get(position);
}
/**
* 获取list中fragment的个数
*
* @return
*/
@Override
public int getCount() {
return list.size();
}
/**
* 返回当前的标题
*
* @param position:当前页面的位置
* @return
*/
@Override
public CharSequence getPageTitle(int position) {
return title[position];
}
}
OK了,现在,我们已经可以实现界面滑动了,但是每个Fragment页面里都是空空的。
好了,现在,来点刺激的,写能显示新闻列表的的FragmentOne。
新闻页面能显示新闻列表,点击新闻进入新闻详情页面
分析——①关于新闻页面使用的是ListView,②然后有ListView就肯定有item的布局还有适配器,③点击进入详情就是设置了Onclick方法,④新闻详情页面博主是用WebView实现的。⑤数据如何获取?博主调用的知乎日报的API接口。
1.界面
就是一个LsitView
2.Activity
新闻页面
注:News和NewsInfo都是实体model类,见到不要蒙圈
前提准备:OkHttpClient包、Gson包、联网授权
1.属性:ListView、OkHttpClient(网络通信异步请求对象)、List列表(NewsInfo是新闻信息的实体类)
2.操作:1.OkHttpClient+Handler请求网络,得到响应数据,并封装到List列表
1).创建Handler,重写handlerMessage方法
2).使用OkHttpClient实现网络异步请求
1.创建Request对象和OkHttpClient对象
2.通过前两个对象创建Call对象
3.通过Call的enqueue(Callback)方法来提交异步请求,子线程
1.把响应字符串转为json对象
2.把json对象转为java对象
3.创建Message对象,初始化后传输给Handler
3).handlerMessage方法中获取List
2.用添加好的List创建列适配器,并添加
3.设置监听,点击跳转详情页面
1).从list中的对象中获取属性
2).通过intent的putExtra设置传输
3).完成跳转
package com.example.tablayoutmenu;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import com.example.tablayoutmenu.model.News;
import com.example.tablayoutmenu.model.NewsInfo;
import com.example.tablayoutmenu.util.JsonUitl;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.List;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
/**
* 新闻页面
注:News和NewsInfo都是实体model类,见到不要蒙圈
前提准备:OkHttpClient包、Gson包、联网授权
1.属性:ListView、OkHttpClient(网络通信异步请求对象)、List列表(NewsInfo是新闻信息的实体类)
2.操作:1.OkHttpClient+Handler请求网络,得到响应数据,并封装到List列表
1).创建Handler,重写handlerMessage方法
2).使用OkHttpClient实现网络异步请求
1.创建Request对象和OkHttpClient对象
2.通过前两个对象创建Call对象
3.通过Call的enqueue(Callback)方法来提交异步请求,子线程
1.把响应字符串转为json对象
2.把json对象转为java对象
3.创建Message对象,初始化后传输给Handler
3).handlerMessage方法中获取List
2.用添加好的List创建列适配器,并添加
3.设置监听,点击跳转详情页面
1).从list中的对象中获取属性
2).通过intent的putExtra设置传输
3).完成跳转
* @author thinkdoor
*/
public class FragmentOne extends Fragment implements AdapterView.OnItemClickListener{
//日志TAG
private static final String TAG = "FragmentOne";
private ListView listView;
//存放新闻信息的列表
private List data;
/**
* 1).创建Handler,重写handlerMessage方法
*/
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
News news = (News)msg.obj;
//3).handlerMessage方法中获取List
data = news.getStories();
List data2 = news.getTop_stories();
//2.用添加好的List创建列适配器,并给ListView添加适配器
listView.setAdapter(new NewsAdapter(data,data2,getContext()));
}
};
/**
* 创建视图
* @param inflater
* @param container
* @param savedInstanceState
* @return
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//用Fragment_one来填充View视图
View view = inflater.inflate(R.layout.fragment_one, container, false);
listView = view.findViewById(R.id.list_view);
listView.setOnItemClickListener(this);
//初始化加载新闻数据
initNews();
return view;
}
/**
* 加载新闻数据,2).使用OkHttpClient实现网络异步请求
*/
public void initNews(){
//知乎新闻
String path = "http://news-at.zhihu.com/api/4/news/latest";
//1.创建Request对象和OkHttpClient对象
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder()
.get()
.url(path)
.build();
//2.通过前两个对象创建Call对象
Call call = okHttpClient.newCall(request);
//3.通过Call的enqueue(Callback)方法来提交异步请求,子线程
call.enqueue(new Callback() {
//请求失败
@Override
public void onFailure(Call call, IOException e) {
Log.d(TAG, "onFailure() called with: call = [" + call + "], e = [" + e + "]");
}
//在子线程中运行的(不能更新UI),请求成功
@Override
public void onResponse(Call call, Response response) throws IOException {
String str = response.body().string();
Log.d(TAG, str);
try {
//1.把响应字符串转为json对象
JSONObject jsonObject = new JSONObject(str);
//2.把json对象转为java对象
News news = (News)JsonUitl.stringToObject(jsonObject.toString(),News.class);
Log.d(TAG, news.toString());
/**
//3.创建Message对象,包装对象后,传输给Handler
*/
Message message = new Message();
message.obj = news;
handler.sendMessage(message);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
/**
* 点击列表item显示新闻详情,取出当前点击的记录,传ID到详情页
*
* @param parent
* @param view
* @param position
* @param id
*/
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
//1).从list中的对象中获取属性
NewsInfo newsInfo = data.get(position);
Intent intent = new Intent();
//2).通过intent的putExtra设置传输
intent.putExtra("id",newsInfo.getId());
//3).完成跳转
intent.setClass(getContext(),NewsDetailActivity.class);
startActivity(intent);
}
}
新闻界面的ListView的适配器
package com.example.tablayoutmenu;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.tablayoutmenu.model.NewsInfo;
import com.example.tablayoutmenu.util.AsyncImageLoader;
import java.util.ArrayList;
import java.util.List;
/**
新闻适配器类
1.因为是List的适配器,所以继承BaseAdapter,并实现必要方法
2.创建需要的List集合
3.重写getView方法实现适配界面
* @author thinkdoor
*/
public class NewsAdapter extends BaseAdapter{
private List list;
//LayoutInflater将布局文件实例化为View对象
private LayoutInflater layoutInflater;
private AsyncImageLoader asyncImageLoader;
public NewsAdapter(List list, Context context){
this.list = list;
layoutInflater = LayoutInflater.from(context);
this.asyncImageLoader = new AsyncImageLoader(context);
}
public NewsAdapter(List list1,List list2, Context context){
this.list = mergeList(list1,list2);
layoutInflater = LayoutInflater.from(context);
this.asyncImageLoader = new AsyncImageLoader(context);
}
/**
* 两个列表合并的方法
*
* @param list1
* @param list2
* @return
*/
public List mergeList(List list1,List list2){
List list = new ArrayList<>();
//遍历列表1,并添加到列表3中
for(int i = 0;i < list1.size();i++){
NewsInfo newsInfo = list1.get(i);
list.add(newsInfo);
}
//遍历列表2,并把String类型的image转化成String[]类型,然后添加到列表3中
for(int i = 0;i < list2.size();i++){
NewsInfo newsInfo = list2.get(i);
newsInfo.setImages(new String[]{newsInfo.getImage()});
list.add(newsInfo);
}
return list;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//将布局文件实例化为View对象
View view = layoutInflater.inflate(R.layout.news_item,null);
//从布局取textview
TextView textView = (TextView)view.findViewById(R.id.textView);
ImageView imageView = (ImageView)view.findViewById(R.id.imageView);
//取当前需要显示的对象
NewsInfo newsInfo = list.get(position);
//给textview赋值
textView.setText(newsInfo.getTitle());
//加载图片
asyncImageLoader.asyncloadImage(imageView, newsInfo.getImages()[0]);
return view;
}
}
新闻详情页面
界面
Activity
package com.example.tablayoutmenu;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.webkit.WebView;
import com.example.tablayoutmenu.model.NewsDetail;
import com.example.tablayoutmenu.util.JsonUitl;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
/**
* 新闻详情页
属性:WebView
操作:1.初始化页面
2.联网请求,得到响应数据,进行处理
1.创建Handler,重写handlerMeassage方法
2.创建OkHttpClient和Request对象
3.创建Call对象
4.重写Call#enqueue(Callback)方法
1.把返回数据转为json对象
2.把json对象转为java对象
3.创建Message,发送数据到主线程
5.handler处理消息
1.得到所需消息
2.WebView赋值
3.完善结尾
*/
public class NewsDetailActivity extends AppCompatActivity {
//日志TAG
private static final String TAG = "NewsDetailActivity";
//创建WebView
private WebView webView;
//创建Handler
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
NewsDetail newsDetail = (NewsDetail)msg.obj;
//用webview加载网页
webView.loadUrl(newsDetail.getShare_url());
}
};
/**
* 创建页面
* @param savedInstanceState
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_news_detail);
webView = (WebView) findViewById(R.id.web_view);
//设置可以执行JS脚本
webView.getSettings().setJavaScriptEnabled(true);
//加载数据
getNews();
}
/**
* 加载新闻数据
*/
public void getNews(){
//知乎新闻详情
String path = "http://news-at.zhihu.com/api/4/news/";
Intent intent = getIntent();
long id = intent.getLongExtra("id",0);
path += id;
//1.创建OkHttpClient对象和Request对象
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder()
.get()
.url(path)
.build();
//2.创建Call对象
Call call = okHttpClient.newCall(request);
//3.执行请求,访问网络数据
call.enqueue(new Callback() {
//请求失败
@Override
public void onFailure(Call call, IOException e) {
Log.d(TAG, "onFailure() called with: call = [" + call + "], e = [" + e + "]");
}
//在子线程中运行的(不能更新UI),请求成功
@Override
public void onResponse(Call call, Response response) throws IOException {
String str = response.body().string();
Log.d(TAG, str);
try {
//1.转换成JSON对象
JSONObject jsonObject = new JSONObject(str);
//2.通过Gson把json字符串转换成java对象
NewsDetail newsDetail
= (NewsDetail) JsonUitl.stringToObject(jsonObject.toString(),NewsDetail.class);
//3.创建Message,发送消息
Message message = new Message();
message.obj = newsDetail;
handler.sendMessage(message);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
/**
* 关闭页面的完善处理
*/
@Override
protected void onDestroy() {
super.onDestroy();
if (webView!=null){
webView.destroy();
}
}
}
后面两个页面举一反三
主要是①联网找API获取到数据,②获取到数据后的处理。
需要打包源码查看下方链接,源码带详细注释,博主用的IDE是Android Studio
https://github.com/Thinkdoor/PractiseSoftware/tree/master