当前位置:   article > 正文

Android开发——项目实例(五)集新闻、音乐、电影于一体的软件(带打包源码)_安卓开发项目

安卓开发项目

主页面

 

1.写界面

很明显,这个主界面采用了ViewPager和TabLayout实现界面滑动切换,在使用TabLayout之前记得导包,TabLayout需要导入的包

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. xmlns:app="http://schemas.android.com/apk/res-auto"
  5. android:id="@+id/activity_main"
  6. android:layout_width="match_parent"
  7. android:layout_height="match_parent"
  8. android:orientation="vertical">
  9. <!--标题区-->
  10. <android.support.design.widget.TabLayout
  11. android:id="@+id/tab_layout"
  12. android:layout_width="match_parent"
  13. android:layout_height="wrap_content"
  14. app:tabGravity="fill"
  15. app:tabMode="fixed"
  16. android:background="#e67bab"
  17. app:tabTextColor="#fff"
  18. app:tabIndicatorColor="#92dfd1"
  19. app:tabSelectedTextColor="#1f67e2"
  20. >
  21. </android.support.design.widget.TabLayout>
  22. <!--页面显示区-->
  23. <android.support.v4.view.ViewPager
  24. android:id="@+id/view_pager"
  25. android:layout_width="match_parent"
  26. android:layout_height="0dp"
  27. android:layout_weight="1"
  28. />
  29. </LinearLayout>

2.写Activity

  1. 登录后的主页面
  2. * 前提:TabLayout依赖的design包
  3. * 属性:①TabLayout、ViewPager
  4. * 操作: 1.初始化一个适配器类
  5. * 1. 定义标题和页面列表
  6. * 2. 把三个Fragment添加到列表中
  7. * 3. 用列表和标题创建适配器
  8. * 2. 进行关联操作
  9. * 1. ViewPager添加适配器
  10. * 2. TabLayout与ViewPager关联
  1. package com.example.tablayoutmenu;
  2. import android.support.design.widget.TabLayout;
  3. import android.support.v4.app.Fragment;
  4. import android.support.v4.view.ViewPager;
  5. import android.support.v7.app.AppCompatActivity;
  6. import android.os.Bundle;
  7. import java.util.ArrayList;
  8. import java.util.List;
  9. /**
  10. * 登录后的主页面
  11. * 前提:TabLayout依赖的design包
  12. * 属性:①TabLayout、ViewPager
  13. * 操作: 1.初始化一个适配器类
  14. * 1. 定义标题和页面列表
  15. * 2. 把三个Fragment添加到列表中
  16. * 3. 用列表和标题创建适配器
  17. * 2. 进行关联操作
  18. * 1. ViewPager添加适配器
  19. * 2. TabLayout与ViewPager关联
  20. *
  21. * @author thinkdoor
  22. */
  23. public class MainActivity extends AppCompatActivity {
  24. /*
  25. 定义UI组件
  26. */
  27. private TabLayout tabLayout;
  28. private ViewPager viewPager;
  29. /**
  30. * 创建的回调方法
  31. *
  32. * @param savedInstanceState
  33. */
  34. @Override
  35. protected void onCreate(Bundle savedInstanceState) {
  36. super.onCreate(savedInstanceState);
  37. setContentView(R.layout.activity_main);
  38. //初始化界面组件
  39. tabLayout = (TabLayout) findViewById(R.id.tab_layout);
  40. viewPager = (ViewPager) findViewById(R.id.view_pager);
  41. //获取初始化的适配器
  42. MyFragmentPagerAdapter myFragmentPagerAdapter = init();
  43. //添加适配器
  44. viewPager.setAdapter(myFragmentPagerAdapter);
  45. //设置tablayou和viewpage关联
  46. tabLayout.setupWithViewPager(viewPager);
  47. }
  48. /**
  49. * 初始化适配器
  50. *
  51. * @return:初始化后的适配器
  52. */
  53. public MyFragmentPagerAdapter init() {
  54. //菜单标题
  55. String[] title = {"新闻", "音乐", "电影"};
  56. //创建装载Fragment的列表
  57. List<Fragment> fragmentlist;
  58. /*
  59. 初始化列表,并把创建的三个Fragment页面添加到列表中
  60. */
  61. fragmentlist = new ArrayList<>();
  62. fragmentlist.add(new FragmentOne());
  63. fragmentlist.add(new FragmentTwo());
  64. fragmentlist.add(new FragmentThree());
  65. //创建Fragment适配器
  66. MyFragmentPagerAdapter myFragmentPagerAdapter;
  67. //适配器进行适配,传入列表与标题
  68. myFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(),
  69. fragmentlist, title);
  70. return myFragmentPagerAdapter;
  71. }
  72. }

3.前面提到了FragmentOne,FragmentTwo,FragmentThree直接创建先放着,记得继承Fragment奥。

4.创建适配器MyFragmentPagerAdpter

  1. fragment的适配器类
  2. * 1.集成FragmentPagerAdapter,实现相关方法
  3. * 2.创建需要显示的List集合
  4. * 3.重写getPageTitle设置标题
  1. package com.example.tablayoutmenu;
  2. import android.support.v4.app.Fragment;
  3. import android.support.v4.app.FragmentManager;
  4. import android.support.v4.app.FragmentPagerAdapter;
  5. import java.util.List;
  6. /**
  7. * fragment的适配器类
  8. * 1.集成FragmentPagerAdapter,实现相关方法
  9. * 2.创建需要显示的List集合
  10. * 3.重写getPageTitle设置标题
  11. *
  12. * @author thinkdoor
  13. */
  14. public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
  15. //装载fragment的列表
  16. private List<Fragment> list;
  17. //标题
  18. private String[] title;
  19. /**
  20. * 构造方法
  21. *
  22. * @param fm
  23. * @param list:装载fragment的列表
  24. * @param title:标题栏
  25. */
  26. public MyFragmentPagerAdapter(FragmentManager fm, List<Fragment> list, String[] title) {
  27. super(fm);
  28. this.list = list;
  29. this.title = title;
  30. }
  31. /**
  32. * 返回当前位置的fragment
  33. *
  34. * @param position:当前页面的位置
  35. * @return
  36. */
  37. @Override
  38. public Fragment getItem(int position) {
  39. return list.get(position);
  40. }
  41. /**
  42. * 获取list中fragment的个数
  43. *
  44. * @return
  45. */
  46. @Override
  47. public int getCount() {
  48. return list.size();
  49. }
  50. /**
  51. * 返回当前的标题
  52. *
  53. * @param position:当前页面的位置
  54. * @return
  55. */
  56. @Override
  57. public CharSequence getPageTitle(int position) {
  58. return title[position];
  59. }
  60. }

OK了,现在,我们已经可以实现界面滑动了,但是每个Fragment页面里都是空空的。

好了,现在,来点刺激的,写能显示新闻列表的的FragmentOne。

新闻页面

新闻页面能显示新闻列表,点击新闻进入新闻详情页面

分析——①关于新闻页面使用的是ListView,②然后有ListView就肯定有item的布局还有适配器,③点击进入详情就是设置了Onclick方法,④新闻详情页面博主是用WebView实现的。⑤数据如何获取?博主调用的知乎日报的API接口。

1.界面

就是一个LsitView

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical"
  6. >
  7. <ListView
  8. android:id="@+id/list_view"
  9. android:layout_width="match_parent"
  10. android:layout_height="match_parent" />
  11. </LinearLayout>

2.Activity

  1. 新闻页面
  2. 注:News和NewsInfo都是实体model类,见到不要蒙圈
  3. 前提准备:OkHttpClient包、Gson包、联网授权
  4. 1.属性:ListView、OkHttpClient(网络通信异步请求对象)、List<NewsInfo>列表(NewsInfo是新闻信息的实体类)
  5. 2.操作:1.OkHttpClient+Handler请求网络,得到响应数据,并封装到List<NewsInfo>列表
  6. 1).创建Handler,重写handlerMessage方法
  7. 2).使用OkHttpClient实现网络异步请求
  8. 1.创建Request对象和OkHttpClient对象
  9. 2.通过前两个对象创建Call对象
  10. 3.通过Call的enqueue(Callback)方法来提交异步请求,子线程
  11. 1.把响应字符串转为json对象
  12. 2.把json对象转为java对象
  13. 3.创建Message对象,初始化后传输给Handler
  14. 3).handlerMessage方法中获取List
  15. 2.用添加好的List创建列适配器,并添加
  16. 3.设置监听,点击跳转详情页面
  17. 1).从list中的对象中获取属性
  18. 2).通过intent的putExtra设置传输
  19. 3).完成跳转
  1. package com.example.tablayoutmenu;
  2. import android.content.Intent;
  3. import android.os.Bundle;
  4. import android.os.Handler;
  5. import android.os.Message;
  6. import android.support.v4.app.Fragment;
  7. import android.util.Log;
  8. import android.view.LayoutInflater;
  9. import android.view.View;
  10. import android.view.ViewGroup;
  11. import android.widget.AdapterView;
  12. import android.widget.ListView;
  13. import com.example.tablayoutmenu.model.News;
  14. import com.example.tablayoutmenu.model.NewsInfo;
  15. import com.example.tablayoutmenu.util.JsonUitl;
  16. import org.json.JSONException;
  17. import org.json.JSONObject;
  18. import java.io.IOException;
  19. import java.util.List;
  20. import okhttp3.Call;
  21. import okhttp3.Callback;
  22. import okhttp3.OkHttpClient;
  23. import okhttp3.Request;
  24. import okhttp3.Response;
  25. /**
  26. * 新闻页面
  27. 注:News和NewsInfo都是实体model类,见到不要蒙圈
  28. 前提准备:OkHttpClient包、Gson包、联网授权
  29. 1.属性:ListView、OkHttpClient(网络通信异步请求对象)、List<NewsInfo>列表(NewsInfo是新闻信息的实体类)
  30. 2.操作:1.OkHttpClient+Handler请求网络,得到响应数据,并封装到List<NewsInfo>列表
  31. 1).创建Handler,重写handlerMessage方法
  32. 2).使用OkHttpClient实现网络异步请求
  33. 1.创建Request对象和OkHttpClient对象
  34. 2.通过前两个对象创建Call对象
  35. 3.通过Call的enqueue(Callback)方法来提交异步请求,子线程
  36. 1.把响应字符串转为json对象
  37. 2.把json对象转为java对象
  38. 3.创建Message对象,初始化后传输给Handler
  39. 3).handlerMessage方法中获取List
  40. 2.用添加好的List创建列适配器,并添加
  41. 3.设置监听,点击跳转详情页面
  42. 1).从list中的对象中获取属性
  43. 2).通过intent的putExtra设置传输
  44. 3).完成跳转
  45. * @author thinkdoor
  46. */
  47. public class FragmentOne extends Fragment implements AdapterView.OnItemClickListener{
  48. //日志TAG
  49. private static final String TAG = "FragmentOne";
  50. private ListView listView;
  51. //存放新闻信息的列表
  52. private List<NewsInfo> data;
  53. /**
  54. * 1).创建Handler,重写handlerMessage方法
  55. */
  56. private Handler handler = new Handler(){
  57. @Override
  58. public void handleMessage(Message msg) {
  59. News news = (News)msg.obj;
  60. //3).handlerMessage方法中获取List
  61. data = news.getStories();
  62. List<NewsInfo> data2 = news.getTop_stories();
  63. //2.用添加好的List创建列适配器,并给ListView添加适配器
  64. listView.setAdapter(new NewsAdapter(data,data2,getContext()));
  65. }
  66. };
  67. /**
  68. * 创建视图
  69. * @param inflater
  70. * @param container
  71. * @param savedInstanceState
  72. * @return
  73. */
  74. @Override
  75. public View onCreateView(LayoutInflater inflater, ViewGroup container,
  76. Bundle savedInstanceState) {
  77. //用Fragment_one来填充View视图
  78. View view = inflater.inflate(R.layout.fragment_one, container, false);
  79. listView = view.findViewById(R.id.list_view);
  80. listView.setOnItemClickListener(this);
  81. //初始化加载新闻数据
  82. initNews();
  83. return view;
  84. }
  85. /**
  86. * 加载新闻数据,2).使用OkHttpClient实现网络异步请求
  87. */
  88. public void initNews(){
  89. //知乎新闻
  90. String path = "http://news-at.zhihu.com/api/4/news/latest";
  91. //1.创建Request对象和OkHttpClient对象
  92. OkHttpClient okHttpClient = new OkHttpClient();
  93. Request request = new Request.Builder()
  94. .get()
  95. .url(path)
  96. .build();
  97. //2.通过前两个对象创建Call对象
  98. Call call = okHttpClient.newCall(request);
  99. //3.通过Call的enqueue(Callback)方法来提交异步请求,子线程
  100. call.enqueue(new Callback() {
  101. //请求失败
  102. @Override
  103. public void onFailure(Call call, IOException e) {
  104. Log.d(TAG, "onFailure() called with: call = [" + call + "], e = [" + e + "]");
  105. }
  106. //在子线程中运行的(不能更新UI),请求成功
  107. @Override
  108. public void onResponse(Call call, Response response) throws IOException {
  109. String str = response.body().string();
  110. Log.d(TAG, str);
  111. try {
  112. //1.把响应字符串转为json对象
  113. JSONObject jsonObject = new JSONObject(str);
  114. //2.把json对象转为java对象
  115. News news = (News)JsonUitl.stringToObject(jsonObject.toString(),News.class);
  116. Log.d(TAG, news.toString());
  117. /**
  118. //3.创建Message对象,包装对象后,传输给Handler
  119. */
  120. Message message = new Message();
  121. message.obj = news;
  122. handler.sendMessage(message);
  123. } catch (JSONException e) {
  124. e.printStackTrace();
  125. }
  126. }
  127. });
  128. }
  129. /**
  130. * 点击列表item显示新闻详情,取出当前点击的记录,传ID到详情页
  131. *
  132. * @param parent
  133. * @param view
  134. * @param position
  135. * @param id
  136. */
  137. @Override
  138. public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  139. //1).从list中的对象中获取属性
  140. NewsInfo newsInfo = data.get(position);
  141. Intent intent = new Intent();
  142. //2).通过intent的putExtra设置传输
  143. intent.putExtra("id",newsInfo.getId());
  144. //3).完成跳转
  145. intent.setClass(getContext(),NewsDetailActivity.class);
  146. startActivity(intent);
  147. }
  148. }

新闻界面的ListView的适配器

  1. package com.example.tablayoutmenu;
  2. import android.content.Context;
  3. import android.view.LayoutInflater;
  4. import android.view.View;
  5. import android.view.ViewGroup;
  6. import android.widget.BaseAdapter;
  7. import android.widget.ImageView;
  8. import android.widget.TextView;
  9. import com.example.tablayoutmenu.model.NewsInfo;
  10. import com.example.tablayoutmenu.util.AsyncImageLoader;
  11. import java.util.ArrayList;
  12. import java.util.List;
  13. /**
  14. 新闻适配器类
  15. 1.因为是List的适配器,所以继承BaseAdapter,并实现必要方法
  16. 2.创建需要的List集合
  17. 3.重写getView方法实现适配界面
  18. * @author thinkdoor
  19. */
  20. public class NewsAdapter extends BaseAdapter{
  21. private List<NewsInfo> list;
  22. //LayoutInflater将布局文件实例化为View对象
  23. private LayoutInflater layoutInflater;
  24. private AsyncImageLoader asyncImageLoader;
  25. public NewsAdapter(List<NewsInfo> list, Context context){
  26. this.list = list;
  27. layoutInflater = LayoutInflater.from(context);
  28. this.asyncImageLoader = new AsyncImageLoader(context);
  29. }
  30. public NewsAdapter(List<NewsInfo> list1,List<NewsInfo> list2, Context context){
  31. this.list = mergeList(list1,list2);
  32. layoutInflater = LayoutInflater.from(context);
  33. this.asyncImageLoader = new AsyncImageLoader(context);
  34. }
  35. /**
  36. * 两个列表合并的方法
  37. *
  38. * @param list1
  39. * @param list2
  40. * @return
  41. */
  42. public List<NewsInfo> mergeList(List<NewsInfo> list1,List<NewsInfo> list2){
  43. List<NewsInfo> list = new ArrayList<>();
  44. //遍历列表1,并添加到列表3中
  45. for(int i = 0;i < list1.size();i++){
  46. NewsInfo newsInfo = list1.get(i);
  47. list.add(newsInfo);
  48. }
  49. //遍历列表2,并把String类型的image转化成String[]类型,然后添加到列表3中
  50. for(int i = 0;i < list2.size();i++){
  51. NewsInfo newsInfo = list2.get(i);
  52. newsInfo.setImages(new String[]{newsInfo.getImage()});
  53. list.add(newsInfo);
  54. }
  55. return list;
  56. }
  57. @Override
  58. public int getCount() {
  59. return list.size();
  60. }
  61. @Override
  62. public Object getItem(int position) {
  63. return list.get(position);
  64. }
  65. @Override
  66. public long getItemId(int position) {
  67. return position;
  68. }
  69. @Override
  70. public View getView(int position, View convertView, ViewGroup parent) {
  71. //将布局文件实例化为View对象
  72. View view = layoutInflater.inflate(R.layout.news_item,null);
  73. //从布局取textview
  74. TextView textView = (TextView)view.findViewById(R.id.textView);
  75. ImageView imageView = (ImageView)view.findViewById(R.id.imageView);
  76. //取当前需要显示的对象
  77. NewsInfo newsInfo = list.get(position);
  78. //给textview赋值
  79. textView.setText(newsInfo.getTitle());
  80. //加载图片
  81. asyncImageLoader.asyncloadImage(imageView, newsInfo.getImages()[0]);
  82. return view;
  83. }
  84. }

新闻详情页面

界面

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. android:id="@+id/activity_news_detail"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. android:paddingBottom="@dimen/activity_vertical_margin"
  8. android:paddingLeft="@dimen/activity_horizontal_margin"
  9. android:paddingRight="@dimen/activity_horizontal_margin"
  10. android:paddingTop="@dimen/activity_vertical_margin"
  11. tools:context="com.example.tablayoutmenu.NewsDetailActivity">
  12. <WebView
  13. android:id="@+id/web_view"
  14. android:layout_width="match_parent"
  15. android:layout_height="match_parent"
  16. android:layout_alignParentTop="true"
  17. android:layout_alignParentStart="true"
  18. />
  19. </RelativeLayout>

Activity

  1. package com.example.tablayoutmenu;
  2. import android.content.Intent;
  3. import android.os.Handler;
  4. import android.os.Message;
  5. import android.support.v7.app.AppCompatActivity;
  6. import android.os.Bundle;
  7. import android.util.Log;
  8. import android.webkit.WebView;
  9. import com.example.tablayoutmenu.model.NewsDetail;
  10. import com.example.tablayoutmenu.util.JsonUitl;
  11. import org.json.JSONException;
  12. import org.json.JSONObject;
  13. import java.io.IOException;
  14. import okhttp3.Call;
  15. import okhttp3.Callback;
  16. import okhttp3.OkHttpClient;
  17. import okhttp3.Request;
  18. import okhttp3.Response;
  19. /**
  20. * 新闻详情页
  21. 属性:WebView
  22. 操作:1.初始化页面
  23. 2.联网请求,得到响应数据,进行处理
  24. 1.创建Handler,重写handlerMeassage方法
  25. 2.创建OkHttpClient和Request对象
  26. 3.创建Call对象
  27. 4.重写Call#enqueue(Callback)方法
  28. 1.把返回数据转为json对象
  29. 2.把json对象转为java对象
  30. 3.创建Message,发送数据到主线程
  31. 5.handler处理消息
  32. 1.得到所需消息
  33. 2.WebView赋值
  34. 3.完善结尾
  35. */
  36. public class NewsDetailActivity extends AppCompatActivity {
  37. //日志TAG
  38. private static final String TAG = "NewsDetailActivity";
  39. //创建WebView
  40. private WebView webView;
  41. //创建Handler
  42. private Handler handler = new Handler(){
  43. @Override
  44. public void handleMessage(Message msg) {
  45. NewsDetail newsDetail = (NewsDetail)msg.obj;
  46. //用webview加载网页
  47. webView.loadUrl(newsDetail.getShare_url());
  48. }
  49. };
  50. /**
  51. * 创建页面
  52. * @param savedInstanceState
  53. */
  54. @Override
  55. protected void onCreate(Bundle savedInstanceState) {
  56. super.onCreate(savedInstanceState);
  57. setContentView(R.layout.activity_news_detail);
  58. webView = (WebView) findViewById(R.id.web_view);
  59. //设置可以执行JS脚本
  60. webView.getSettings().setJavaScriptEnabled(true);
  61. //加载数据
  62. getNews();
  63. }
  64. /**
  65. * 加载新闻数据
  66. */
  67. public void getNews(){
  68. //知乎新闻详情
  69. String path = "http://news-at.zhihu.com/api/4/news/";
  70. Intent intent = getIntent();
  71. long id = intent.getLongExtra("id",0);
  72. path += id;
  73. //1.创建OkHttpClient对象和Request对象
  74. OkHttpClient okHttpClient = new OkHttpClient();
  75. Request request = new Request.Builder()
  76. .get()
  77. .url(path)
  78. .build();
  79. //2.创建Call对象
  80. Call call = okHttpClient.newCall(request);
  81. //3.执行请求,访问网络数据
  82. call.enqueue(new Callback() {
  83. //请求失败
  84. @Override
  85. public void onFailure(Call call, IOException e) {
  86. Log.d(TAG, "onFailure() called with: call = [" + call + "], e = [" + e + "]");
  87. }
  88. //在子线程中运行的(不能更新UI),请求成功
  89. @Override
  90. public void onResponse(Call call, Response response) throws IOException {
  91. String str = response.body().string();
  92. Log.d(TAG, str);
  93. try {
  94. //1.转换成JSON对象
  95. JSONObject jsonObject = new JSONObject(str);
  96. //2.通过Gson把json字符串转换成java对象
  97. NewsDetail newsDetail
  98. = (NewsDetail) JsonUitl.stringToObject(jsonObject.toString(),NewsDetail.class);
  99. //3.创建Message,发送消息
  100. Message message = new Message();
  101. message.obj = newsDetail;
  102. handler.sendMessage(message);
  103. } catch (JSONException e) {
  104. e.printStackTrace();
  105. }
  106. }
  107. });
  108. }
  109. /**
  110. * 关闭页面的完善处理
  111. */
  112. @Override
  113. protected void onDestroy() {
  114. super.onDestroy();
  115. if (webView!=null){
  116. webView.destroy();
  117. }
  118. }
  119. }

后面两个页面举一反三

主要是①联网找API获取到数据,②获取到数据后的处理

音乐界面

电影页面

需要打包源码查看下方链接,源码带详细注释,博主用的IDE是Android Studio

GitHub - Thinkdoor/PractiseSoftware

要是觉得还可以,点个再走吧!求求了~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/251962
推荐阅读
相关标签
  

闽ICP备14008679号