赞
踩
1.写界面
很明显,这个主界面采用了ViewPager和TabLayout实现界面滑动切换,在使用TabLayout之前记得导包,TabLayout需要导入的包。
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:id="@+id/activity_main"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
-
- <!--标题区-->
- <android.support.design.widget.TabLayout
- android:id="@+id/tab_layout"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- app:tabGravity="fill"
- app:tabMode="fixed"
- android:background="#e67bab"
- app:tabTextColor="#fff"
- app:tabIndicatorColor="#92dfd1"
- app:tabSelectedTextColor="#1f67e2"
- >
- </android.support.design.widget.TabLayout>
-
- <!--页面显示区-->
- <android.support.v4.view.ViewPager
- android:id="@+id/view_pager"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1"
- />
-
- </LinearLayout>
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<Fragment> 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<Fragment> list;
-
- //标题
- private String[] title;
-
- /**
- * 构造方法
- *
- * @param fm
- * @param list:装载fragment的列表
- * @param title:标题栏
- */
- public MyFragmentPagerAdapter(FragmentManager fm, List<Fragment> 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
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- >
-
- <ListView
- android:id="@+id/list_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
- </LinearLayout>
2.Activity
- 新闻页面
-
- 注:News和NewsInfo都是实体model类,见到不要蒙圈
- 前提准备:OkHttpClient包、Gson包、联网授权
- 1.属性:ListView、OkHttpClient(网络通信异步请求对象)、List<NewsInfo>列表(NewsInfo是新闻信息的实体类)
- 2.操作:1.OkHttpClient+Handler请求网络,得到响应数据,并封装到List<NewsInfo>列表
- 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>列表(NewsInfo是新闻信息的实体类)
- 2.操作:1.OkHttpClient+Handler请求网络,得到响应数据,并封装到List<NewsInfo>列表
- 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<NewsInfo> 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<NewsInfo> 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<NewsInfo> list;
- //LayoutInflater将布局文件实例化为View对象
- private LayoutInflater layoutInflater;
-
- private AsyncImageLoader asyncImageLoader;
-
- public NewsAdapter(List<NewsInfo> list, Context context){
- this.list = list;
- layoutInflater = LayoutInflater.from(context);
- this.asyncImageLoader = new AsyncImageLoader(context);
- }
-
- public NewsAdapter(List<NewsInfo> list1,List<NewsInfo> list2, Context context){
- this.list = mergeList(list1,list2);
- layoutInflater = LayoutInflater.from(context);
- this.asyncImageLoader = new AsyncImageLoader(context);
- }
- /**
- * 两个列表合并的方法
- *
- * @param list1
- * @param list2
- * @return
- */
- public List<NewsInfo> mergeList(List<NewsInfo> list1,List<NewsInfo> list2){
- List<NewsInfo> 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;
- }
- }
新闻详情页面
界面
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:id="@+id/activity_news_detail"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingBottom="@dimen/activity_vertical_margin"
- android:paddingLeft="@dimen/activity_horizontal_margin"
- android:paddingRight="@dimen/activity_horizontal_margin"
- android:paddingTop="@dimen/activity_vertical_margin"
- tools:context="com.example.tablayoutmenu.NewsDetailActivity">
-
- <WebView
- android:id="@+id/web_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_alignParentTop="true"
- android:layout_alignParentStart="true"
- />
- </RelativeLayout>
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
GitHub - Thinkdoor/PractiseSoftware
要是觉得还可以,点个再走吧!求求了~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。