小项目之新闻客户端

最近写了一个简单的新闻客户端app+后台服务,主要是为了熟悉巩固一下知识点,增加编码熟练度吐舌头


首先来画主界面


实现上图中的页面布局,主要是分成了三部分

最外层使用LinearLayout

[html]  view plain  copy
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:layout_width="match_parent"  
  3.     android:layout_height="match_parent"  
  4.     android:orientation="vertical">  
  5. </LinearLayout>  

第一部分RelativeLayout

[html]  view plain  copy
  1. <RelativeLayout  
  2.     android:layout_width="match_parent"  
  3.     android:layout_height="50dip"  
  4.     android:background="#3C3C3C">  
  5.     <TextView  
  6.         android:id="@+id/main_hand_title"  
  7.         android:layout_width="wrap_content"  
  8.         android:layout_height="wrap_content"  
  9.         android:layout_marginLeft="10dp"  
  10.         android:layout_marginTop="12dp"  
  11.         android:text="新闻客户端"  
  12.         android:textColor="#e7e7e7"  
  13.         android:textSize="18sp" />  
  14.     <ImageView  
  15.         android:id="@+id/main_hand_refresh"  
  16.         android:layout_width="30dip"  
  17.         android:layout_height="30dip"  
  18.         android:layout_alignParentRight="true"  
  19.         android:layout_marginRight="10dip"  
  20.         android:layout_marginTop="10dip"  
  21.         android:onClick="titleBar_image_click"  
  22.         android:src="@drawable/main_hand_refresh" />  
  23. </RelativeLayout>  

扫描二维码关注公众号,回复: 1713065 查看本文章

第二部分RelativeLayout

[html]  view plain  copy
  1. <RelativeLayout  
  2.     android:layout_width="match_parent"  
  3.     android:layout_height="50dp"  
  4.     android:layout_marginTop="1dp"  
  5.     android:background="#3C3C3C">  
  6.     <HorizontalScrollView  
  7.         android:id="@+id/main_category_scroll"  
  8.         android:layout_width="wrap_content"  
  9.         android:layout_height="wrap_content"  
  10.         android:layout_centerVertical="true"  
  11.         android:layout_toLeftOf="@id/main_category_button"  
  12.         android:scrollbars="none">  
  13.         <LinearLayout  
  14.             android:id="@+id/main_category_linear"  
  15.             android:layout_width="wrap_content"  
  16.             android:layout_height="wrap_content"  
  17.             android:orientation="horizontal" />  
  18.     </HorizontalScrollView>  
  19.     <Button  
  20.         android:id="@+id/main_category_button"  
  21.         android:layout_width="35dip"  
  22.         android:layout_height="35dip"  
  23.         android:layout_alignParentRight="true"  
  24.         android:layout_centerVertical="true"  
  25.         android:background="@drawable/main_category_button" />  
  26. </RelativeLayout>  

第三部分是ListView,那为了有下拉刷新的效果,在外层嵌套了SwipeRefreshLayout

[html]  view plain  copy
  1. <android.support.v4.widget.SwipeRefreshLayout  
  2.     android:layout_width="match_parent"  
  3.     android:layout_height="match_parent">  
  4.     <ListView  
  5.         android:id="@+id/main_body_list"  
  6.         android:layout_width="match_parent"  
  7.         android:layout_height="match_parent"  
  8.         android:divider="@drawable/line"  
  9.         android:fadeScrollbars="false"  
  10.         android:listSelector="@drawable/main_body_list_selector"  
  11.         android:scrollbarFadeDuration="0"></ListView>  
  12. </android.support.v4.widget.SwipeRefreshLayout>  

接着实现MainActivity代码

[java]  view plain  copy
  1. package com.mynews.activity;  
  2.   
  3. import android.app.ActionBar;  
  4. import android.graphics.Color;  
  5. import android.graphics.drawable.ColorDrawable;  
  6. import android.os.AsyncTask;  
  7. import android.os.Handler;  
  8. import android.os.Message;  
  9. import android.support.v7.app.AppCompatActivity;  
  10. import android.os.Bundle;  
  11. import android.view.Gravity;  
  12. import android.view.View;  
  13. import android.view.ViewGroup;  
  14. import android.widget.AbsListView;  
  15. import android.widget.AdapterView;  
  16. import android.widget.BaseAdapter;  
  17. import android.widget.Button;  
  18. import android.widget.GridView;  
  19. import android.widget.HorizontalScrollView;  
  20. import android.widget.ImageView;  
  21. import android.widget.LinearLayout;  
  22. import android.widget.ListView;  
  23. import android.widget.ProgressBar;  
  24. import android.widget.SimpleAdapter;  
  25. import android.widget.TextView;  
  26.   
  27. import com.mynews.R;  
  28. import com.mynews.model.News;  
  29. import com.mynews.utils.DensityUtil;  
  30. import com.mynews.utils.GetPinyin;  
  31. import com.mynews.utils.PicassoUtil;  
  32.   
  33. import org.apache.http.HttpEntity;  
  34. import org.apache.http.HttpResponse;  
  35. import org.apache.http.client.HttpClient;  
  36. import org.apache.http.client.methods.HttpGet;  
  37. import org.apache.http.impl.client.DefaultHttpClient;  
  38. import org.apache.http.util.EntityUtils;  
  39. import org.json.JSONArray;  
  40. import org.json.JSONObject;  
  41.   
  42. import java.util.ArrayList;  
  43. import java.util.HashMap;  
  44. import java.util.List;  
  45. import java.util.Map;  
  46.   
  47. public class MainActivity extends AppCompatActivity {  
  48.   
  49.     private String CURRENTCATEGORY = "toutiao";  //点击的类别的拼音  
  50.     private int COUNT = 1;  //分页的记录值  
  51.     private List<News> newsList = new ArrayList<>();  //新闻的集合  
  52.     private ListView mainBodyList;   //列表listView  
  53.     private View mainBodyListBottom;  //listView底部  
  54.     private TextView mainBodyListBottomTV;  //listView底部的TextView  
  55.     private ProgressBar mainBodyListBottomPB;  //listView底部的进度条  
  56.     private NewsAdapter newsAdapter;  //新闻适配器  
  57.   
  58.     @Override  
  59.     protected void onCreate(Bundle savedInstanceState) {  
  60.         super.onCreate(savedInstanceState);  
  61.         setContentView(R.layout.activity_main);  
  62.         mainBodyList = findViewById(R.id.main_body_list);  
  63.   
  64.         //<-----------------------------------设置点击按钮滚动标题栏---------------------------------------  
  65.         final HorizontalScrollView category_scrollview = findViewById(R.id.main_category_scroll);  
  66.         Button main_category_button = findViewById(R.id.main_category_button);  
  67.         main_category_button.setOnClickListener(new View.OnClickListener() {  
  68.             @Override  
  69.             public void onClick(View view) {  
  70.                 category_scrollview.fling(DensityUtil.px2dip(MainActivity.this1500)); //滚动方法  
  71.             }  
  72.         });  
  73.         //--------------------------------------------------------------------------------------->  
  74.   
  75.         //-----------------------------------设置点击按钮滚动标题栏--------------------------------------->  
  76.         int columnWidth = 400;  //分类间隔距离 px  
  77.         String[] categoryArray = getResources().getStringArray(R.array.main_category_item);  //分类信息  
  78.         List<Map<String, String>> categorys = new ArrayList<>();  
  79.         for (int i = 0; i < categoryArray.length; i++) {  
  80.             Map<String, String> map = new HashMap<>();  
  81.             map.put("main_category_item", categoryArray[i]);  
  82.             categorys.add(map);  
  83.         }  
  84.         SimpleAdapter categoryAdapter = new SimpleAdapter(this, categorys, R.layout.main_category_item, new String[]{"main_category_item"}, new int[]{R.id.main_category_item});  
  85.         //创建网格视图  
  86.         GridView gridView = new GridView(this);  
  87.         gridView.setNumColumns(GridView.AUTO_FIT);  //列数设置为自动  
  88.         gridView.setSelector(new ColorDrawable(Color.TRANSPARENT));  //设置选中颜色为透明色  
  89.         gridView.setColumnWidth(DensityUtil.px2dip(this, columnWidth));  //设置列宽,DensityUtil.px2dip()转换px为dip的工具类方法  
  90.         gridView.setGravity(Gravity.CENTER);  //设置对齐方式  
  91.         int dipColumnWidth = DensityUtil.px2dip(this, columnWidth) * categorys.size();  
  92.         ActionBar.LayoutParams params = new ActionBar.LayoutParams(dipColumnWidth, ActionBar.LayoutParams.WRAP_CONTENT);  
  93.         gridView.setLayoutParams(params);  
  94.         gridView.setAdapter(categoryAdapter);  
  95.         LinearLayout categoryLinearlayout = findViewById(R.id.main_category_linear);  
  96.         categoryLinearlayout.addView(gridView);  
  97.         //<---------------------------------------------------------------------------------------  
  98.   
  99.         //-----------------------------------item的点击事件监听--------------------------------------->  
  100.         gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {  
  101.             @Override  
  102.             public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {  
  103.                 TextView categoryTitle;  
  104.                 //这个循环主要作用清空所有item的背景,并设置初始颜色  
  105.                 for (int j = 0; j < adapterView.getCount(); j++) {  
  106.                     ((TextView) adapterView.getChildAt(j)).setTextColor(getResources().getColor(R.color.color_ADB2AD));  
  107.                     adapterView.getChildAt(j).setBackgroundDrawable(null);  
  108.                 }  
  109.                 CURRENTCATEGORY = GetPinyin.getPingYin(((TextView) view).getText().toString());  //设置点击后的类别拼音,此处的工具类需要导包 pinyin4j-2.5.0.jar  
  110.                 COUNT = 1//分页的记录值  
  111.                 categoryTitle = (TextView) view;  
  112.                 categoryTitle.setTextColor(getResources().getColor(R.color.color_FFFFFF));  
  113.                 categoryTitle.setBackgroundResource(R.drawable.main_category_item_selector);  
  114.   
  115.                 newsList = new ArrayList<>();  //清空新闻list  
  116.                 mainBodyList.removeFooterView(mainBodyListBottom);  //清除底部view  
  117.                 new NewsTask().execute(getResources().getString(R.string.issue) + "news?type=" + CURRENTCATEGORY);  //异步请求数据 R.string.issue=http://10.0.2.2:8080/news/api/  
  118.   
  119.             }  
  120.         });  
  121.         //<---------------------------------------------------------------------------------------  
  122.   
  123.         //-----------------------------------listVIew的拖动监听事件监听--------------------------------------->  
  124.         mainBodyList.setOnScrollListener(new AbsListView.OnScrollListener() {  
  125.             @Override  
  126.             public void onScrollStateChanged(AbsListView view, int scrollState) {  
  127.                 if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {  //停止滑动状态  
  128.                     if (view.getLastVisiblePosition() == (view.getCount() - 1)) {   //滑动到listView的最后  
  129.                         mainBodyListBottomTV.setVisibility(View.GONE);  //隐藏  
  130.                         mainBodyListBottomPB.setVisibility(View.VISIBLE);  //显示  
  131.                         new Thread(new Runnable() {  
  132.                             @Override  
  133.                             public void run() {  
  134.                                 try {  
  135.                                     addData(getResources().getString(R.string.issue) + "news?type=" + CURRENTCATEGORY, COUNT);  
  136.                                     handler.sendEmptyMessage(2);  
  137.                                 } catch (Exception e) {  
  138.                                     e.printStackTrace();  
  139.                                 }  
  140.                             }  
  141.                         }).start();  
  142.                     }  
  143.                 }  
  144.             }  
  145.             @Override  
  146.             public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {  
  147.             }  
  148.         });  
  149.         //<---------------------------------------------------------------------------------------  
  150.   
  151.         new NewsTask().execute(getResources().getString(R.string.issue) + "news?type=" + CURRENTCATEGORY);  //初始化加载  
  152.     }  
  153.   
  154.     class NewsTask extends AsyncTask<String, Void, List<News>> {  
  155.         @Override  
  156.         protected void onPreExecute() {  
  157.             super.onPreExecute();  
  158.         }  
  159.   
  160.         @Override  
  161.         protected List<News> doInBackground(String... strings) {  
  162.             //使用httpclient需要在app目录下的build.gradle文件中的Android里面加上useLibrary 'org.apache.http.legacy' /*加载 HttpClient*/  
  163.             HttpClient httpClient = new DefaultHttpClient();  
  164.             HttpGet httpGet = new HttpGet(strings[0]);  
  165.             try {  
  166.                 HttpResponse httpResponse = httpClient.execute(httpGet);  
  167.                 if (httpResponse.getStatusLine().getStatusCode() == 200) {  
  168.                     HttpEntity entity = httpResponse.getEntity();  
  169.                     String json = EntityUtils.toString(entity, "utf-8");  
  170.                     JSONArray jsonArray = new JSONObject(json).getJSONArray("pdList");  
  171.                     for (int i = 0; i < jsonArray.length(); i++) {  
  172.                         JSONObject element = jsonArray.getJSONObject(i);  
  173.                         News news = new News();  
  174.                         news.setNEWSDETAIL_ID(element.getString("NEWSDETAIL_ID"));  
  175.                         news.setUNIQUEKEY(element.getString("UNIQUEKEY"));  
  176.                         news.setTITLE(element.getString("TITLE"));  
  177.                         news.setURL(element.getString("URL"));  
  178.                         news.setDATE(element.getString("DATE"));  
  179.                         news.setPIC1(element.getString("PIC1"));  
  180.                         news.setCATEGORY(element.getString("CATEGORY"));  
  181.                         news.setCOMMENT(element.getString("COMMENT"));  
  182.                         newsList.add(news);  
  183.                     }  
  184.                 }  
  185.             } catch (Exception e) {  
  186.                 e.printStackTrace();  
  187.             }  
  188.             return newsList;  
  189.         }  
  190.   
  191.         @Override  
  192.         protected void onPostExecute(List<News> newsList) {  
  193.             super.onPostExecute(newsList);  
  194.             mainBodyListBottom = getLayoutInflater().inflate(R.layout.main_body_list_bottom, null);  
  195.             mainBodyListBottomTV = mainBodyListBottom.findViewById(R.id.main_body_list_bottom_tv);  
  196.             mainBodyListBottomPB = mainBodyListBottom.findViewById(R.id.main_body_list_bottom_pb);  
  197.             if (newsList.size() == 0) {  
  198.                 mainBodyListBottomTV.setText("暂无新闻");  
  199.             }  
  200.             mainBodyList.addFooterView(mainBodyListBottom);  
  201.             mainBodyList.setAdapter(newsAdapter = new NewsAdapter(newsList));  
  202.   
  203.             handler.sendEmptyMessage(1);  
  204.         }  
  205.     }  
  206.   
  207.     class NewsAdapter extends BaseAdapter {  
  208.         public List<News> data;  
  209.         public NewsAdapter(List<News> data) {  
  210.             this.data = data;  
  211.         }  
  212.         @Override  
  213.         public int getCount() {  
  214.             return data.size();  
  215.         }  
  216.         @Override  
  217.         public Object getItem(int i) {  
  218.             return i;  
  219.         }  
  220.         @Override  
  221.         public long getItemId(int i) {  
  222.             return 0;  
  223.         }  
  224.         @Override  
  225.         public View getView(int i, View view, ViewGroup viewGroup) {  
  226.             NewsList newsList;  
  227.             if (view == null) {  
  228.                 newsList = new NewsList();  
  229.                 view = getLayoutInflater().inflate(R.layout.main_body_list_item, viewGroup, false);  
  230.                 newsList.imageView = view.findViewById(R.id.imageView);  
  231.                 newsList.textView1 = view.findViewById(R.id.tv_title);  
  232.                 newsList.textView2 = view.findViewById(R.id.tv_below);  
  233.                 view.setTag(newsList);  
  234.             } else {  
  235.                 newsList = (NewsList) view.getTag();  
  236.             }  
  237.             newsList.textView1.setText(data.get(i).getTITLE());  
  238.             newsList.textView2.setText(data.get(i).getDATE());  
  239.             PicassoUtil.loadImageWithHodler(MainActivity.this, data.get(i).getPIC1(), R.drawable.loading, newsList.imageView);  //使用picasso加载图片资源  
  240.             return view;  
  241.         }  
  242.     }  
  243.   
  244.     class NewsList {  
  245.         ImageView imageView;  
  246.         TextView textView1;  
  247.         TextView textView2;  
  248.     }  
  249.   
  250.     /** 
  251.      * * 加载分页数据 
  252.      * 
  253.      * @param count 第几页 
  254.      * @param path  地址 
  255.      */  
  256.     private void addData(String path, int count) {  
  257.         HttpClient httpClient = new DefaultHttpClient();  
  258.         HttpGet httpGet = new HttpGet(path + "&count=" + count);  
  259.         try {  
  260.             HttpResponse httpResponse = httpClient.execute(httpGet);  
  261.             if (httpResponse.getStatusLine().getStatusCode() == 200) {  
  262.                 HttpEntity entity = httpResponse.getEntity();  
  263.                 String json = EntityUtils.toString(entity, "utf-8");  
  264.                 JSONArray jsonArray = new JSONObject(json).getJSONArray("pdList");  
  265.                 for (int i = 0; i < jsonArray.length(); i++) {  
  266.                     JSONObject element = jsonArray.getJSONObject(i);  
  267.                     News news = new News();  
  268.                     news.setNEWSDETAIL_ID(element.getString("NEWSDETAIL_ID"));  
  269.                     news.setUNIQUEKEY(element.getString("UNIQUEKEY"));  
  270.                     news.setTITLE(element.getString("TITLE"));  
  271.                     news.setURL(element.getString("URL"));  
  272.                     news.setDATE(element.getString("DATE"));  
  273.                     news.setPIC1(element.getString("PIC1"));  
  274.                     news.setCATEGORY(element.getString("CATEGORY"));  
  275.                     news.setCOMMENT(element.getString("COMMENT"));  
  276.                     newsList.add(news);  
  277.                 }  
  278.             }  
  279.         } catch (Exception e) {  
  280.             e.printStackTrace();  
  281.         }  
  282.     }  
  283.   
  284.     private Handler handler = new Handler() {  
  285.         @Override  
  286.         public void handleMessage(Message msg) {  
  287.             if (msg.what == 1) {  
  288.   
  289.             }else if(msg.what == 2){  //数据加载完毕  
  290.                 mainBodyListBottomPB.setVisibility(View.GONE);  //隐藏进度条  
  291.                 mainBodyListBottomTV.setVisibility(View.VISIBLE);  //显示底部textView  
  292.                 newsAdapter.notifyDataSetChanged();//刷新listview  
  293.                 COUNT++;  
  294.             }  
  295.         }  
  296.     };  
  297. }  

补充:后台服务端代码和接口,点击这里

看看效果,基本实现了主要功能。但是细节做的不太好,找图片资源太耗时了。



接着实现新闻详情界面,顶部的左右箭头绑定了ViewFlipper 的nextView方法  和previousView方法,跟帖数随着发帖数量增加



新闻详情布局主要分为三个部分

最外层使用相对布局

[html]  view plain  copy
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:id="@+id/new_detail_rl"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent">  
  5. </RelativeLayout>  

第一部分

[html]  view plain  copy
  1. <RelativeLayout  
  2.         android:id="@+id/news_detail_hand_relative"  
  3.         android:layout_width="match_parent"  
  4.         android:layout_height="50dip"  
  5.         android:background="@color/color_D32204">  
  6.   
  7.         <Button  
  8.             android:id="@+id/news_detail_hand_relative_btn_left"  
  9.             android:layout_width="35dip"  
  10.             android:layout_height="35dip"  
  11.             android:layout_alignParentLeft="true"  
  12.             android:layout_marginTop="6dip"  
  13.             android:background="@drawable/zuo" />  
  14.   
  15.         <TextView  
  16.             android:id="@+id/news_detail_hand_relative_tv_category"  
  17.             android:layout_width="wrap_content"  
  18.             android:layout_height="wrap_content"  
  19.             android:layout_marginLeft="10dip"  
  20.             android:layout_marginVertical="13dip"  
  21.             android:layout_toEndOf="@+id/news_detail_hand_relative_btn_left"  
  22.             android:textSize="18sp" />  
  23.   
  24.         <Button  
  25.             android:id="@+id/news_detail_hand_relative_btn_comment"  
  26.             android:layout_width="wrap_content"  
  27.             android:layout_height="wrap_content"  
  28.             android:layout_alignParentRight="true"  
  29.             android:layout_marginRight="20dip"  
  30.             android:background="#00000000" />  
  31.   
  32.         <Button  
  33.             android:id="@+id/news_detail_hand_relative_btn_right"  
  34.             android:layout_width="35dip"  
  35.             android:layout_height="35dip"  
  36.             android:layout_alignParentRight="true"  
  37.             android:layout_marginTop="6dip"  
  38.             android:background="@drawable/you" />  
  39.     </RelativeLayout>  

第二部分,使用ViewFlipper能够加载多个body主体,并能通过方法切换

[html]  view plain  copy
  1. <ViewFlipper  
  2.     android:id="@+id/news_detail_body_flipper"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:layout_below="@+id/news_detail_hand_relative"  
  6.     android:layout_marginBottom="40dip"></ViewFlipper>  

第三部分

[html]  view plain  copy
  1. <LinearLayout  
  2.     android:layout_width="match_parent"  
  3.     android:layout_height="40dip"  
  4.     android:layout_alignParentBottom="true"  
  5.     android:layout_centerHorizontal="true"  
  6.     android:background="@drawable/background"  
  7.     android:gravity="center"  
  8.     android:orientation="horizontal"  
  9.     android:visibility="visible">  
  10.   
  11.     <LinearLayout  
  12.         android:id="@+id/news_detail_bottom_ll_01"  
  13.         android:layout_width="wrap_content"  
  14.         android:layout_height="wrap_content"  
  15.         android:layout_gravity="center"  
  16.         android:layout_marginTop="3dip"  
  17.         android:gravity="center"  
  18.         android:orientation="horizontal"  
  19.         android:visibility="gone">  
  20.   
  21.         <EditText  
  22.             android:id="@+id/news_detail_bottom_ll_01_et_comment"  
  23.             android:layout_width="290dip"  
  24.             android:layout_height="40dip"  
  25.             android:layout_marginLeft="2dip" />  
  26.   
  27.         <TextView  
  28.             android:layout_width="wrap_content"  
  29.             android:layout_height="wrap_content"  
  30.             android:text="|" />  
  31.   
  32.         <!--发表-->  
  33.         <Button  
  34.             android:id="@+id/btn_send"  
  35.             android:layout_width="70dip"  
  36.             android:layout_height="40dip"  
  37.             android:layout_marginLeft="2dip"  
  38.             android:layout_marginRight="2dip"  
  39.             android:text="发表" />  
  40.   
  41.     </LinearLayout>  
  42.   
  43.     <LinearLayout  
  44.         android:id="@+id/news_detail_bottom_ll_02"  
  45.         android:layout_width="wrap_content"  
  46.         android:layout_height="wrap_content"  
  47.         android:layout_gravity="center"  
  48.         android:layout_marginTop="3dip"  
  49.         android:gravity="center"  
  50.         android:orientation="horizontal">  
  51.   
  52.         <ImageButton  
  53.             android:id="@+id/news_detail_bottom_ll_02_ib_write"  
  54.             android:layout_width="290dip"  
  55.             android:layout_height="40dip"  
  56.             android:layout_marginLeft="2dip"  
  57.             android:background="#00000000"  
  58.             android:src="@drawable/button" />  
  59.   
  60.         <TextView  
  61.             android:layout_width="wrap_content"  
  62.             android:layout_height="wrap_content"  
  63.             android:layout_marginLeft="7dip"  
  64.             android:text="|" />  
  65.   
  66.         <!--收藏-->  
  67.         <Button  
  68.             android:id="@+id/news_detail_bottom_ll_02_btn_collect"  
  69.             android:layout_width="60dip"  
  70.             android:layout_height="40dip"  
  71.             android:layout_marginLeft="2dip"  
  72.             android:layout_marginRight="2dip"  
  73.             android:text="收藏" />  
  74.   
  75.     </LinearLayout>  
  76.   
  77. </LinearLayout>  


编写NewsDetailActivity 先把MainActivity中ListView的item点击事件补上

[java]  view plain  copy
  1. //-----------------------------------listView的item点击事件--------------------------------------->  
  2.         mainBodyList.setOnItemClickListener(new AdapterView.OnItemClickListener() {  
  3.             @Override  
  4.             public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {  
  5.                 Intent intent = new Intent(MainActivity.this, NewsDetailActivity.class);  
  6.                 Bundle bundle = new Bundle();  
  7.                 bundle.putSerializable("list", (Serializable) newsList);//序列化,要注意转化(Serializable)  
  8.                 intent.putExtra("list", bundle);  
  9.                 intent.putExtra("i", i);  
  10.                 startActivity(intent);  
  11.             }  
  12.         });  
  13.         //<---------------------------------------------------------------------------------------  
编写NewsDetailActivity

[java]  view plain  copy
  1. package com.mynews.activity;  
  2.   
  3. import android.app.Activity;  
  4. import android.app.AlertDialog;  
  5. import android.content.DialogInterface;  
  6. import android.content.Intent;  
  7. import android.os.Bundle;  
  8. import android.os.Handler;  
  9. import android.os.Message;  
  10. import android.support.annotation.Nullable;  
  11. import android.util.Log;  
  12. import android.view.LayoutInflater;  
  13. import android.view.MotionEvent;  
  14. import android.view.View;  
  15. import android.view.ViewGroup;  
  16. import android.webkit.WebView;  
  17. import android.widget.BaseAdapter;  
  18. import android.widget.Button;  
  19. import android.widget.EditText;  
  20. import android.widget.ImageButton;  
  21. import android.widget.LinearLayout;  
  22. import android.widget.ProgressBar;  
  23. import android.widget.TextView;  
  24. import android.widget.Toast;  
  25. import android.widget.ViewFlipper;  
  26.   
  27. import com.mynews.R;  
  28. import com.mynews.dao.CollectDao;  
  29. import com.mynews.model.Collect;  
  30. import com.mynews.model.News;  
  31.   
  32. import org.apache.http.HttpEntity;  
  33. import org.apache.http.HttpResponse;  
  34. import org.apache.http.client.HttpClient;  
  35. import org.apache.http.client.methods.HttpGet;  
  36. import org.apache.http.impl.client.DefaultHttpClient;  
  37. import org.apache.http.util.EntityUtils;  
  38. import org.json.JSONObject;  
  39.   
  40. import java.net.URLEncoder;  
  41. import java.util.List;  
  42.   
  43. /** 
  44.  * Created by Administrator on 2017/12/28. 
  45.  */  
  46.   
  47. public class NewsDetailActivity extends Activity implements View.OnClickListener{  
  48.   
  49.     private String TAG = NewsDetailActivity.class.getSimpleName();  
  50.     private Intent intent;  //意图对象  
  51.     private int COUNT = 0;  //记录页数  
  52.     private List<News> newsList;  //传递过来的list集合  
  53.     private TextView tvCategory;  //头部显示新闻类别的文本控件  
  54.     private Button btnComment;    //头部的跟帖按钮  
  55.     private ViewFlipper viewFlipper;  //view容器  
  56.     private LayoutInflater layoutInflater;  
  57.     private ProgressBar newsDetailBodyPB;  //主体部分的进度条  
  58.     private int mStartX = 0;  
  59.       
  60.     private Button newsDetailHandRelativeBtnLeft; //上一篇按钮  
  61.     private Button newsDetailHandRelativeBtnRight;  //下一篇按钮  
  62.     private ImageButton newsDetailBottomLl02IbWrite;  //图片按钮  
  63.     private Button newsDetailBottomLl01BtnSend;  //发送跟帖按钮  
  64.     private Button newsDetailBottomLl02BtnCollect;  //收藏按钮  
  65.   
  66.     private long downTime;  //收藏按钮按下的时间  
  67.     private long upTime;  //收藏按钮按下的记录时间  
  68.     private volatile boolean onBtnTouch = false;  //是否按下按钮  
  69.   
  70.     @Override  
  71.     protected void onCreate(@Nullable Bundle savedInstanceState) {  
  72.         super.onCreate(savedInstanceState);  
  73.         setContentView(R.layout.news_detail);  
  74.   
  75.         //-----------------------------------获取MainActivity传递的参数------------------------------------->  
  76.         intent = getIntent();  //获取意图对象  
  77.         Bundle bundle = intent.getBundleExtra("list");  //获取新闻集合  
  78.         newsList = (List<News>) bundle.getSerializable("list");  //新闻集合  
  79.         COUNT = intent.getIntExtra("i"0);  //获取MainActivity点击的item的位置  
  80.   
  81.         //设置头部的新闻类别  
  82.         tvCategory = findViewById(R.id.news_detail_hand_relative_tv_category);  
  83.         tvCategory.setText(newsList.get(COUNT).getCATEGORY());  
  84.   
  85.         //设置头部的跟帖数  
  86.         btnComment = findViewById(R.id.news_detail_hand_relative_btn_comment);  
  87.         btnComment.setText(newsList.get(COUNT).getCOMMENT() + "跟帖");  
  88.   
  89.         //设置显示新闻主体  
  90.         viewFlipper = findViewById(R.id.news_detail_body_flipper);  
  91.         layoutInflater = getLayoutInflater();  
  92.   
  93.         //使用打气筒构造内容主体body  
  94.         View view = layoutInflater.inflate(R.layout.news_detail_body, null);  
  95.   
  96.         //设置进度条按钮显示  
  97.         newsDetailBodyPB = view.findViewById(R.id.news_detail_body_pb);  
  98.         newsDetailBodyPB.setVisibility(View.VISIBLE);  
  99.   
  100.         //viewFlipper.removeAllViews();  
  101.         for (int i = 0; i < newsList.size(); i++) {  
  102.             View inflate = layoutInflater.inflate(R.layout.news_detail_body, null);  
  103.             WebView newsDetailBodyWV = inflate.findViewById(R.id.news_detail_body_wv);  
  104.             newsDetailBodyWV.loadUrl(newsList.get(i).getURL());  //设置webView加载URL内容  
  105.             viewFlipper.addView(inflate, i);  //把构造的主体内容加入到viewFlipper容器中  
  106.   
  107.             //绑定主体的触摸监听事件  
  108.             newsDetailBodyWV.setOnTouchListener(new View.OnTouchListener() {  
  109.                 @Override  
  110.                 public boolean onTouch(View view, MotionEvent motionEvent) {  
  111.                     switch (motionEvent.getAction()) {  
  112.                         case MotionEvent.ACTION_DOWN:  //手指按下触发  
  113.                             //按下时的横坐标  
  114.                             mStartX = (int) motionEvent.getX();  
  115.                             break;  
  116.                         case MotionEvent.ACTION_UP:  //手指抬起触发  
  117.                             //像左滑动  
  118.                             if (motionEvent.getX() < mStartX) {  
  119.                                 nextView();  
  120.                             } else if (motionEvent.getX() > mStartX) {  //向右滑动  
  121.                                 previousView();  
  122.                             }  
  123.                             break;  
  124.                     }  
  125.                     return true;  
  126.                 }  
  127.             });  
  128.         }  
  129.         viewFlipper.setDisplayedChild(COUNT);  //设置第几个view显示  
  130.         newsDetailBodyPB.setVisibility(View.GONE);  //进度条隐藏  
  131.         //<--------------------------------------------------------------------------------------------------  
  132.           
  133.         //---------------------------------------------设置点击事件---------------------------------------------------->  
  134.         newsDetailHandRelativeBtnLeft = findViewById(R.id.news_detail_hand_relative_btn_left);//上一页  
  135.         newsDetailHandRelativeBtnRight = findViewById(R.id.news_detail_hand_relative_btn_right);//下一页  
  136.         newsDetailBottomLl02IbWrite = findViewById(R.id.news_detail_bottom_ll_02_ib_write);//写跟帖  
  137.         newsDetailBottomLl01BtnSend = findViewById(R.id.news_detail_bottom_ll_01_btn_send);//发表  
  138.         newsDetailHandRelativeBtnLeft.setOnClickListener(this);  
  139.         newsDetailHandRelativeBtnRight.setOnClickListener(this);  
  140.         newsDetailBottomLl02IbWrite.setOnClickListener(this);  
  141.         newsDetailBottomLl01BtnSend.setOnClickListener(this);  
  142.         //------------------------------------------------------------------------------------------------->  
  143.   
  144.         //---------------------------------------------设置收藏点击事件---------------------------------------------------->  
  145.         newsDetailBottomLl02BtnCollect = findViewById(R.id.news_detail_bottom_ll_02_btn_collect); //收藏 按钮是否被按下  
  146.         newsDetailBottomLl02BtnCollect.setOnTouchListener(new View.OnTouchListener() {  
  147.             @Override  
  148.             public boolean onTouch(View view, MotionEvent motionEvent) {  
  149.                 if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {  
  150.                     downTime = System.currentTimeMillis();  
  151.                     onBtnTouch = true;  
  152.                     Thread t = new Thread() {  
  153.                         @Override  
  154.                         public void run() {  
  155.                             while (onBtnTouch) {  
  156.                                 upTime = System.currentTimeMillis();  
  157.                                 try {  
  158.                                     Thread.sleep(100);  
  159.                                 } catch (Exception e) {  
  160.                                     e.printStackTrace();  
  161.                                 }  
  162.                             }  
  163.                         }  
  164.                     };  
  165.                     t.start();  
  166.                 } else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {  
  167.                     onBtnTouch = false;  
  168.                     if (upTime - downTime > 500) {  
  169.                         handler.sendEmptyMessage(3);  //按下按钮超过0.5秒  
  170.                     } else {  
  171.                         handler.sendEmptyMessage(2);  
  172.                     }  
  173.                 } else if (motionEvent.getAction() == MotionEvent.ACTION_CANCEL) {  //手指按下移开时触发事件  
  174.                     onBtnTouch = false;  
  175.                 }  
  176.   
  177.                 return true;  
  178.   
  179.             }  
  180.         });  
  181.         //------------------------------------------------------------------------------------------------->  
  182.   
  183.     }  
  184.   
  185.     @Override  
  186.     public void onClick(View view) {  
  187.         //点击的是上一页  
  188.         if (view.getId() == newsDetailHandRelativeBtnLeft.getId()) {  
  189.             previousView();  
  190.         } else if (view.getId() == newsDetailHandRelativeBtnRight.getId()) {  //点击的是下一页  
  191.             nextView();  
  192.         } else if (view.getId() == newsDetailBottomLl02IbWrite.getId()) {  //点击的是写跟贴  
  193.             LinearLayout ll01 = findViewById(R.id.news_detail_bottom_ll_01);  
  194.             ll01.setVisibility(View.VISIBLE);  
  195.             LinearLayout ll02 = findViewById(R.id.news_detail_bottom_ll_02);  
  196.             ll02.setVisibility(View.GONE);  
  197.         } else if (view.getId() == newsDetailBottomLl01BtnSend.getId()) {  //点击的是发表  
  198.   
  199.             final EditText etComment = findViewById(R.id.news_detail_bottom_ll_01_et_comment);  
  200.             new Thread(new Runnable() {  
  201.                 @Override  
  202.                 public void run() {  
  203.                     try {  
  204.   
  205.                         StringBuffer sb = new StringBuffer();  
  206.                         sb.append("content=");  
  207.                         sb.append(URLEncoder.encode(etComment.getText().toString().trim(), "UTF-8"));  
  208.                         sb.append("&newsdetailId=");  
  209.                         sb.append(newsList.get(COUNT).getNEWSDETAIL_ID());  
  210.                         String path = getResources().getString(R.string.issue) + "addComment?" + sb.toString();  
  211.                         addComment(path);  
  212.                     } catch (Exception e) {  
  213.                         e.printStackTrace();  
  214.                     }  
  215.                 }  
  216.             }).start();  
  217.             Toast.makeText(this"保存成功!", Toast.LENGTH_SHORT).show();  
  218.   
  219.             LinearLayout ll01 = findViewById(R.id.news_detail_bottom_ll_01);  
  220.             ll01.setVisibility(View.GONE);  
  221.             LinearLayout ll02 = findViewById(R.id.news_detail_bottom_ll_02);  
  222.             ll02.setVisibility(View.VISIBLE);  
  223.         }  
  224.     }  
  225.   
  226.     /** 
  227.      * 添加跟帖 
  228.      * 
  229.      * @param path 路径 
  230.      */  
  231.     private void addComment(String path) throws Exception {  
  232.         HttpClient httpClient = new DefaultHttpClient();  
  233.         HttpGet httpGet = new HttpGet(path);  
  234.         HttpResponse httpResponse;  
  235.         try {  
  236.             httpGet.addHeader("Content-Type""application/x-www-form-urlencoded; charset=utf-8");  
  237.             httpResponse = httpClient.execute(httpGet);  
  238.             if (httpResponse.getStatusLine().getStatusCode() == 200) {  
  239.                 HttpEntity entity = httpResponse.getEntity();  
  240.                 String result = EntityUtils.toString(entity, "utf-8");  
  241.                 // String status = new JSONObject(result).getString("message");  
  242.                 // String message = new JSONObject(result).getString("status");  
  243.                 String count = new JSONObject(result).getString("count");  
  244.   
  245.                 Message message1 = Message.obtain();  
  246.                 message1.obj = count;  
  247.                 message1.what = 1;  
  248.                 handler.sendMessage(message1);  
  249.   
  250.             }  
  251.         } catch (Exception e) {  
  252.             e.printStackTrace();  
  253.         }  
  254.     }  
  255.   
  256.     //点击的是下一页  
  257.     private void nextView() {  
  258.         COUNT++;  
  259.         Log.i(TAG, "nextView: count-->" + COUNT);  
  260.         if (COUNT <= newsList.size() - 1) {  
  261.             showNext();  
  262.         } else {  
  263.             COUNT = newsList.size() - 1;  
  264.             Toast.makeText(this"已经是最后一条啦!", Toast.LENGTH_SHORT).show();  
  265.         }  
  266.   
  267.   
  268.     }  
  269.   
  270.     //上一页  
  271.     private void previousView() {  
  272.         COUNT--;  
  273.         Log.i(TAG, "previousView: count-->" + COUNT);  
  274.         if (COUNT >= 0) {  
  275.             showPrevious();  
  276.         } else {  
  277.             COUNT = 0;  
  278.             Toast.makeText(this"已经是第一条啦!", Toast.LENGTH_SHORT).show();  
  279.         }  
  280.     }  
  281.   
  282.     //上一条  
  283.     private void showPrevious() {  
  284.         btnComment.setText(newsList.get(COUNT).getCOMMENT() + "跟帖");  //设置每条新闻对应的跟帖数量  
  285.         //设置动画效果  
  286.         viewFlipper.setInAnimation(NewsDetailActivity.this, R.anim.push_right_in);  
  287.         viewFlipper.setOutAnimation(NewsDetailActivity.this, R.anim.push_right_out);  
  288.         viewFlipper.showPrevious();  //调用viewFlipper的上一条方法  
  289.     }  
  290.   
  291.     //下一条  
  292.     private void showNext() {  
  293.         btnComment.setText(newsList.get(COUNT).getCOMMENT() + "跟帖"); //设置每条新闻对应的跟帖数量  
  294.         //设置动画效果  
  295.         viewFlipper.setInAnimation(NewsDetailActivity.this, R.anim.push_left_in);  
  296.         viewFlipper.setOutAnimation(NewsDetailActivity.this, R.anim.push_left_out);  
  297.         viewFlipper.showNext();//调用viewFlipper的下一条方法  
  298.     }  
  299.   
  300.   
  301.     /** 
  302.      * 创建一个列表弹窗 
  303.      */  
  304.     private void createListDialog(final List<Collect> collects) {  
  305.         AlertDialog.Builder builder = new AlertDialog.Builder(this);  
  306.         builder.setTitle("收藏列表:");  
  307.         builder.setAdapter(new CollectAdapter(collects), new DialogInterface.OnClickListener() {  
  308.             /** 
  309.              * 
  310.              * @param dialogInterface 当前的对话框 
  311.              * @param i 当前点击的是列表的第几个 item 
  312.              */  
  313.             @Override  
  314.             public void onClick(DialogInterface dialogInterface, int i) {  
  315.                 Intent intent = new Intent(NewsDetailActivity.this, CollectNewsDetailActivity.class);  
  316.                 intent.putExtra("newsdetailId", collects.get(i).getNewsdetailId());  
  317.                 startActivity(intent);  
  318.             }  
  319.         });  
  320.         builder.setCancelable(true);//允许被某些方式取消,比如按对话框之外的区域或者是返回键  
  321.         builder.show();  
  322.     }  
  323.   
  324.     class CollectAdapter extends BaseAdapter {  
  325.         private List<Collect> collects;  
  326.         public CollectAdapter(List<Collect> collects) {  
  327.             this.collects = collects;  
  328.         }  
  329.         @Override  
  330.         public int getCount() {  
  331.             return collects.size();  
  332.         }  
  333.         @Override  
  334.         public Object getItem(int i) {  
  335.             return i;  
  336.         }  
  337.         @Override  
  338.         public long getItemId(int i) {  
  339.             return 0;  
  340.         }  
  341.         @Override  
  342.         public View getView(int i, View view, ViewGroup viewGroup) {  
  343.             CollectDialog collectDialog;  
  344.             if (view == null) {  
  345.                 collectDialog = new CollectDialog();  
  346.                 view = getLayoutInflater().inflate(R.layout.news_detail_collect_dialog, viewGroup, false);  
  347.                 collectDialog.tv1 = view.findViewById(R.id.btn_collect_dialog_title);  
  348.                 collectDialog.tv2 = view.findViewById(R.id.btn_collect_dialog_date);  
  349.                 view.setTag(collectDialog);  
  350.             } else {  
  351.                 collectDialog = (CollectDialog) view.getTag();  
  352.             }  
  353.             collectDialog.tv1.setText(collects.get(i).getTitle());  
  354.             collectDialog.tv2.setText(collects.get(i).getDate());  
  355.             return view;  
  356.         }  
  357.     }  
  358.   
  359.     class CollectDialog {  
  360.         TextView tv1;  
  361.         TextView tv2;  
  362.     }  
  363.   
  364.     private Handler handler = new Handler(){  
  365.         CollectDao collectDao = new CollectDao(NewsDetailActivity.this);  
  366.   
  367.         @Override  
  368.         public void handleMessage(Message msg) {  
  369.             if (msg.what == 1) {  
  370.                 String count = (String) msg.obj;  
  371.                 btnComment.setText(count + "跟帖");  
  372.             } else if (msg.what == 2) {  
  373.                 List<Collect> collects = collectDao.queryBuilder1(newsList.get(COUNT).getNEWSDETAIL_ID());  
  374.                 if (collects.size() <= 0) {  
  375.                     Collect collect = new Collect();  
  376.                     collect.setNewsdetailId(newsList.get(COUNT).getNEWSDETAIL_ID());  
  377.                     collect.setTitle(newsList.get(COUNT).getTITLE());  
  378.                     collect.setDate(newsList.get(COUNT).getDATE());  
  379.                     collectDao.addCollect(collect);  
  380.                     Toast.makeText(NewsDetailActivity.this"收藏成功,长按可查看收藏哦!", Toast.LENGTH_SHORT).show();  
  381.                 } else {  
  382.                     Toast.makeText(NewsDetailActivity.this"已收藏该文章,长按可查看收藏哦!", Toast.LENGTH_SHORT).show();  
  383.                 }  
  384.             } else if (msg.what == 3) {  
  385.                 createListDialog(collectDao.listAll());  
  386.             }  
  387.         }  
  388.     };  
  389. }  

NewsDetailActivity 部分在保存收藏文章时使用了ORMLite,需要导入两个jar文件,并且需要编写一个Helper类和一个Dao类。具体看文章最后补上的源码。



接着画下一个布局,界面很简单,直接看代码



布局文件

[html]  view plain  copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:background="@color/color_E7E7E7"  
  6.     android:orientation="vertical">  
  7.   
  8.     <RelativeLayout  
  9.         android:id="@+id/comment_list_hand"  
  10.         android:layout_width="match_parent"  
  11.         android:layout_height="50dip"  
  12.         android:background="@color/color_D32204">  
  13.   
  14.         <TextView  
  15.             android:id="@+id/comment_list_hand_TV"  
  16.             android:layout_width="wrap_content"  
  17.             android:layout_height="wrap_content"  
  18.             android:layout_marginLeft="18dip"  
  19.             android:layout_marginTop="12dip"  
  20.             android:text="跟帖"  
  21.             android:textColor="@color/color_E7E7E7"  
  22.             android:textSize="18sp" />  
  23.   
  24.         <Button  
  25.             android:id="@+id/comment_list_hand_BTN"  
  26.             android:layout_width="60dip"  
  27.             android:layout_height="45dip"  
  28.             android:layout_alignParentRight="true"  
  29.             android:layout_marginRight="10dip"  
  30.             android:layout_marginTop="4dip"  
  31.             android:text="原文"/>  
  32.     </RelativeLayout>  
  33.   
  34.     <ListView  
  35.         android:id="@+id/comment_list_body"  
  36.         android:layout_width="match_parent"  
  37.         android:layout_height="match_parent"  
  38.         android:layout_below="@+id/comment_list_hand"  
  39.         android:cacheColorHint="#00000000"  
  40.         android:divider="@drawable/line"  
  41.         android:layout_marginBottom="40dip">  
  42.     </ListView>  
  43.   
  44.     <LinearLayout  
  45.         android:layout_width="match_parent"  
  46.         android:layout_height="40dip"  
  47.         android:layout_alignParentBottom="true"  
  48.         android:layout_centerHorizontal="true"  
  49.         android:background="@drawable/background"  
  50.         android:gravity="center"  
  51.         android:orientation="horizontal"  
  52.         android:visibility="visible">  
  53.   
  54.         <LinearLayout  
  55.             android:layout_width="wrap_content"  
  56.             android:layout_height="wrap_content"  
  57.             android:layout_gravity="center"  
  58.             android:layout_marginTop="3dip"  
  59.             android:gravity="center"  
  60.             android:orientation="horizontal">  
  61.   
  62.             <EditText  
  63.                 android:id="@+id/comment_list_bottom_ET"  
  64.                 android:layout_width="290dip"  
  65.                 android:layout_height="40dip"  
  66.                 android:layout_marginLeft="2dip" />  
  67.   
  68.             <TextView  
  69.                 android:layout_width="wrap_content"  
  70.                 android:layout_height="wrap_content"  
  71.                 android:text="|" />  
  72.   
  73.             <!--发表-->  
  74.             <Button  
  75.                 android:id="@+id/comment_list_bottom_BTN"  
  76.                 android:layout_width="70dip"  
  77.                 android:layout_height="40dip"  
  78.                 android:layout_marginLeft="2dip"  
  79.                 android:layout_marginRight="2dip"  
  80.                 android:text="发表" />  
  81.   
  82.         </LinearLayout>  
  83.   
  84.     </LinearLayout>  
  85.   
  86. </RelativeLayout>  

编写CommentActivity

[java]  view plain  copy
  1. package com.mynews.activity;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Context;  
  5. import android.os.AsyncTask;  
  6. import android.os.Bundle;  
  7. import android.os.Handler;  
  8. import android.os.Message;  
  9. import android.support.annotation.Nullable;  
  10. import android.view.View;  
  11. import android.view.ViewGroup;  
  12. import android.view.inputmethod.InputMethodManager;  
  13. import android.widget.BaseAdapter;  
  14. import android.widget.Button;  
  15. import android.widget.EditText;  
  16. import android.widget.ListView;  
  17. import android.widget.TextView;  
  18. import android.widget.Toast;  
  19.   
  20. import com.mynews.R;  
  21. import com.mynews.model.Comment;  
  22. import com.mynews.utils.DateUtil;  
  23.   
  24. import org.apache.http.HttpEntity;  
  25. import org.apache.http.HttpResponse;  
  26. import org.apache.http.client.HttpClient;  
  27. import org.apache.http.client.methods.HttpGet;  
  28. import org.apache.http.impl.client.DefaultHttpClient;  
  29. import org.apache.http.util.EntityUtils;  
  30. import org.json.JSONArray;  
  31. import org.json.JSONObject;  
  32.   
  33. import java.net.URLEncoder;  
  34. import java.util.ArrayList;  
  35. import java.util.List;  
  36.   
  37. /** 
  38.  * Created by Administrator on 2017/12/28. 
  39.  */  
  40.   
  41. public class CommentActivity extends Activity {  
  42.   
  43.     private EditText commentListBottomET;  //底部的输入框控件  
  44.     private Button commentListBottomBTN;  //底部的发表按钮  
  45.     private List<Comment> commentList;  //跟帖集合  
  46.     private CommentAdapter commentAdapter;  //跟帖的适配器  
  47.     private ListView commentListView;  //跟帖的listView  
  48.     private TextView commentListHandTV;  
  49.     private Button commentListHandBTN;  
  50.   
  51.     @Override  
  52.     protected void onCreate(@Nullable Bundle savedInstanceState) {  
  53.         super.onCreate(savedInstanceState);  
  54.         setContentView(R.layout.comment_list);  
  55.   
  56.         commentListHandTV = findViewById(R.id.comment_list_hand_TV);  
  57.         commentListView = findViewById(R.id.comment_list_body);  
  58.   
  59.         //-----------------------------------原文按钮点击事件----------------------------------------->  
  60.         commentListHandBTN = findViewById(R.id.comment_list_hand_BTN);  
  61.         commentListHandBTN.setOnClickListener(new View.OnClickListener() {  
  62.             @Override  
  63.             public void onClick(View view) {  
  64.                 finish();  
  65.             }  
  66.         });  
  67.         //<-------------------------------------------------------------------------------------  
  68.   
  69.         //-----------------------------------发表按钮点击事件----------------------------------------->  
  70.         commentListBottomBTN = findViewById(R.id.comment_list_bottom_BTN); //获取发表按钮  
  71.         commentListBottomET = findViewById(R.id.comment_list_bottom_ET);   //获取editText按钮  
  72.         commentListBottomBTN.setOnClickListener(new View.OnClickListener() {  
  73.             @Override  
  74.             public void onClick(View view) {  
  75.                 new Thread(new Runnable() {  
  76.                     @Override  
  77.                     public void run() {  
  78.                         try {  
  79.                             String commentContent = commentListBottomET.getText().toString().trim();  
  80.                             StringBuffer sb = new StringBuffer();  
  81.                             sb.append("content=");  
  82.                             sb.append(URLEncoder.encode(commentContent, "UTF-8"));  
  83.                             sb.append("&newsdetailId=");  
  84.                             sb.append(getIntent().getStringExtra("newsdetailId"));  
  85.                             String path = getResources().getString(R.string.issue) + "addComment?" + sb.toString();  
  86.                             addComment(path);  
  87.   
  88.                             Comment comment = new Comment();  
  89.                             comment.setDATE(DateUtil.getTime());  
  90.                             comment.setCONTENT(commentContent);  
  91.                             commentList.add(comment);  
  92.                             handler.sendEmptyMessage(2);  
  93.   
  94.                         } catch (Exception e) {  
  95.                             e.printStackTrace();  
  96.                         }  
  97.                     }  
  98.                 }).start();  
  99.             }  
  100.         });  
  101.   
  102.         new CommentTask().execute(getResources().getString(R.string.issue) + "commentList?newsdetailId=" + getIntent().getStringExtra("newsdetailId"));  
  103.     }  
  104.   
  105.     class CommentAdapter extends BaseAdapter {  
  106.   
  107.         private List<Comment> commentList;  
  108.   
  109.         public CommentAdapter(List<Comment> commentList) {  
  110.             this.commentList = commentList;  
  111.         }  
  112.   
  113.         @Override  
  114.         public int getCount() {  
  115.             return commentList.size();  
  116.         }  
  117.   
  118.         @Override  
  119.         public Object getItem(int i) {  
  120.             return i;  
  121.         }  
  122.   
  123.         @Override  
  124.         public long getItemId(int i) {  
  125.             return 0;  
  126.         }  
  127.   
  128.         @Override  
  129.         public View getView(int i, View view, ViewGroup viewGroup) {  
  130.             Comment1 comment1;  
  131.             if (view == null) {  
  132.                 comment1 = new Comment1();  
  133.                 view = getLayoutInflater().inflate(R.layout.comment_list_item, viewGroup, false);  
  134.                 comment1.tv1 = view.findViewById(R.id.comment_list_item_tv1);  
  135.                 comment1.tv2 = view.findViewById(R.id.comment_list_item_tv2);  
  136.                 comment1.tv3 = view.findViewById(R.id.comment_list_item_tv3);  
  137.                 view.setTag(comment1);  
  138.             } else {  
  139.                 comment1 = (Comment1) view.getTag();  
  140.             }  
  141.             comment1.tv1.setText(commentList.get(i).getDATE());  
  142.             comment1.tv2.setText(commentList.get(i).getCOMMENTID());  
  143.             comment1.tv3.setText(commentList.get(i).getCONTENT());  
  144.             return view;  
  145.         }  
  146.     }  
  147.   
  148.     class Comment1 {  
  149.         TextView tv1;  
  150.         TextView tv2;  
  151.         TextView tv3;  
  152.     }  
  153.   
  154.     class CommentTask extends AsyncTask<String, Void, List<Comment>> {  
  155.   
  156.         @Override  
  157.         protected void onPreExecute() {  
  158.             super.onPreExecute();  
  159.         }  
  160.   
  161.         @Override  
  162.         protected List<Comment> doInBackground(String... strings) {  
  163.             commentList = new ArrayList<>();  
  164.             HttpClient httpClient = new DefaultHttpClient();  
  165.             HttpGet httpGet = new HttpGet(strings[0]);  
  166.             try {  
  167.                 HttpResponse httpResponse = httpClient.execute(httpGet);  
  168.                 if (httpResponse.getStatusLine().getStatusCode() == 200) {  
  169.                     HttpEntity entity = httpResponse.getEntity();  
  170.                     String json = EntityUtils.toString(entity, "utf-8");  
  171.                     JSONArray jsonArray = new JSONObject(json).getJSONArray("pdList");  
  172.                     for (int i = 0; i < jsonArray.length(); i++) {  
  173.                         JSONObject element = jsonArray.getJSONObject(i);  
  174.                         Comment comment = new Comment();  
  175.                         comment.setCOMMENTID(element.getString("COMMENT_ID"));  
  176.                         comment.setDATE(element.getString("DATE"));  
  177.                         comment.setCONTENT(element.getString("CONTENT"));  
  178.                         commentList.add(comment);  
  179.                     }  
  180.                 }  
  181.             } catch (Exception e) {  
  182.                 e.printStackTrace();  
  183.             }  
  184.             return commentList;  
  185.         }  
  186.   
  187.         @Override  
  188.         protected void onPostExecute(List<Comment> commentList) {  
  189.             super.onPostExecute(commentList);  
  190.             commentListView.setAdapter(commentAdapter = new CommentAdapter(commentList));  
  191.         }  
  192.     }  
  193.   
  194.     /** 
  195.      * 添加跟帖 
  196.      * 
  197.      * @param path 路径 
  198.      */  
  199.     private void addComment(String path) throws Exception {  
  200.         //Log.i(TAG, "addComment: path------>>" + path);  
  201.         HttpClient httpClient = new DefaultHttpClient();  
  202.         HttpGet httpGet = new HttpGet(path);  
  203.         HttpResponse httpResponse;  
  204.         try {  
  205.             httpGet.addHeader("Content-Type""application/x-www-form-urlencoded; charset=utf-8");  
  206.             //httpGet.addHeader("charset", HTTP.UTF_8);  
  207.             httpResponse = httpClient.execute(httpGet);  
  208.             if (httpResponse.getStatusLine().getStatusCode() == 200) {  
  209.                 HttpEntity entity = httpResponse.getEntity();  
  210.                 String result = EntityUtils.toString(entity, "utf-8");  
  211.                 String status = new JSONObject(result).getString("message");  
  212.                 String message = new JSONObject(result).getString("status");  
  213.                 String count = new JSONObject(result).getString("count");  
  214.                 Message message1 = Message.obtain();  
  215.                 message1.obj = count;  
  216.                 message1.what = 1;  
  217.                 handler.sendMessage(message1);  
  218.             }  
  219.         } catch (Exception e) {  
  220.             e.printStackTrace();  
  221.         }  
  222.     }  
  223.   
  224.     private Handler handler = new Handler() {  
  225.         @Override  
  226.         public void handleMessage(Message msg) {  
  227.             if (msg.what == 1) {  
  228.                 String count = (String) msg.obj;  
  229.                 commentListHandTV.setText("跟帖 " + count + "条");  
  230.                 Toast.makeText(CommentActivity.this"发帖成功!", Toast.LENGTH_LONG).show();  
  231.             } else if (msg.what == 2) {  
  232.                 commentAdapter.notifyDataSetChanged();//刷新listview  
  233.                 commentListBottomET.setText("");  //清空文本  
  234.                 commentListBottomET.clearFocus();  //清除焦点  
  235.                 //软键盘隐藏  
  236.                 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);  
  237.                 imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);  
  238.             }  
  239.         }  
  240.     };  
  241.   
  242. }  


到此主要的功能以及基本实现,现在再来给主界面添加上版本更新的代码,让程序每次启动检查是否有新版本,并提示用户是否更新

[java]  view plain  copy
  1. package com.mynews.dao;  
  2.   
  3. import android.app.AlertDialog;  
  4. import android.app.Dialog;  
  5. import android.content.Context;  
  6. import android.content.DialogInterface;  
  7. import android.content.Intent;  
  8. import android.net.Uri;  
  9. import android.os.Build;  
  10. import android.support.v4.content.FileProvider;  
  11. import android.util.Log;  
  12. import android.view.LayoutInflater;  
  13. import android.view.View;  
  14. import android.widget.ProgressBar;  
  15. import android.widget.TextView;  
  16.   
  17. import com.mynews.BuildConfig;  
  18. import com.mynews.R;  
  19.   
  20. import java.io.File;  
  21. import java.io.FileOutputStream;  
  22. import java.io.InputStream;  
  23. import java.net.HttpURLConnection;  
  24. import java.net.URL;  
  25. import java.util.Map;  
  26.   
  27. public class VersionDao {  
  28.   
  29.     private Context context;  
  30.     private Map<String, String> map;  //服务器端最新app信息  
  31.     private volatile boolean cancelUpdate;  //下载状态  
  32.     private ProgressBar pbNewsDeatil;  
  33.     private Dialog downloadDialog;  
  34.     private String TAG = VersionDao.class.getSimpleName();  
  35.   
  36.     public VersionDao(Context context, Map<String, String> map) {  
  37.         this.context = context;  
  38.         this.map = map;  
  39.     }  
  40.   
  41.     public void checkUpdate() {  
  42.         Log.i(TAG, "checkUpdate: 版本更新");  
  43.         if (isUpdate()) {  
  44.             showNoticeDialog();  
  45.         }  
  46.     }  
  47.   
  48.     private boolean isUpdate() {  
  49.         //获取当前软件版本号  
  50.         String versionName = getVersionName();  
  51.         //Log.i(TAG, "isUpdate: versionName=" + versionName);  
  52.         //Log.i(TAG, "isUpdate: NUMBER=" + map.get("NUMBER").toString());  
  53.         if (!versionName.equals(map.get("NUMBER").toString())) {  //版本号字符串不相等时更新  
  54.             return true;  
  55.         }  
  56.         return false;  
  57.     }  
  58.   
  59.     /** 
  60.      * 当前应用版本号 
  61.      * 
  62.      * @return 版本号 
  63.      */  
  64.     private String getVersionName() {  
  65.         String versionName = null;  
  66.         try {  
  67.             //通过上下文对象获取版本号  
  68.             versionName = context.getPackageManager().getPackageInfo("com.gm.news"0).versionName;  
  69.         } catch (Exception e) {  
  70.             e.printStackTrace();  
  71.         }  
  72.         return versionName;  
  73.     }  
  74.   
  75.     private void showNoticeDialog() {  
  76.         //构造对话框  
  77.         AlertDialog.Builder builder = new AlertDialog.Builder(context);  
  78.         builder.setTitle("版本更新提示");  
  79.         builder.setMessage("检测到新版本," + map.get("CONTENT").toString());  
  80.         //更新  
  81.         builder.setPositiveButton("更新"new DialogInterface.OnClickListener() {  
  82.             @Override  
  83.             public void onClick(DialogInterface dialogInterface, int i) {  
  84.                 dialogInterface.dismiss();  //隐藏更新对话框  
  85.                 showDownloadDialog();  //显示下载进度对话框  
  86.             }  
  87.         });  
  88.   
  89.         //稍后更新  
  90.         builder.setNegativeButton("稍后更新"new DialogInterface.OnClickListener() {  
  91.             @Override  
  92.             public void onClick(DialogInterface dialogInterface, int i) {  
  93.                 dialogInterface.dismiss();  
  94.             }  
  95.         });  
  96.         Dialog noticeDialog = builder.create();  
  97.         noticeDialog.show();  
  98.     }  
  99.   
  100.     private void showDownloadDialog() {  
  101.         Log.i(TAG, "showDownloadDialog: 弹出更新对话框");  
  102.         AlertDialog.Builder builder = new AlertDialog.Builder(context);  
  103.         builder.setTitle("更新进度:");  
  104.         LayoutInflater layoutInflater = LayoutInflater.from(context);  
  105.         View view = layoutInflater.inflate(R.layout.main_softupload_progress, null);  
  106.         pbNewsDeatil = view.findViewById(R.id.pb_newsDetail);  
  107.         TextView tv_version_content = view.findViewById(R.id.tv_version_content);  
  108.         tv_version_content.setText(map.get("CONTENT").toString());  //版本更新的内容  
  109.         builder.setView(view);  
  110.         //取消  
  111.         builder.setNegativeButton("取消"new DialogInterface.OnClickListener() {  
  112.             @Override  
  113.             public void onClick(DialogInterface dialogInterface, int i) {  
  114.                 dialogInterface.dismiss();  
  115.                 //设置取消状态  
  116.                 cancelUpdate = false;  
  117.             }  
  118.         });  
  119.   
  120.         downloadDialog = builder.create();  
  121.         downloadDialog.show();  
  122.         cancelUpdate = true;  //开始下载  
  123.         //下载文件  
  124.         download();  
  125.   
  126.     }  
  127.   
  128.     //下载文件  
  129.     private void download() {  
  130.         Log.i(TAG, "download: 下载文件中");  
  131.         new Thread(new Runnable() {  
  132.             @Override  
  133.             public void run() {  
  134.                 try {  
  135.   
  136.                     URL url = new URL(map.get("PATH").toString());  
  137.                     HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
  138.                     conn.setRequestMethod("GET");  
  139.                     conn.setConnectTimeout(5000);  
  140.                     int code = conn.getResponseCode();  
  141.                     if (code == HttpURLConnection.HTTP_OK) {  
  142.                         File file = new File(context.getFilesDir().getPath() + "/mynews.apk");  
  143.                         FileOutputStream fos = new FileOutputStream(file);  
  144.                         float length = conn.getContentLength();  
  145.                         InputStream in = conn.getInputStream();  
  146.                         float total = 0;  
  147.                         int len = -1;  
  148.                         byte[] buffer = new byte[100];  
  149.                         int progress;  
  150.                         while ((len = in.read(buffer)) != -1) {  
  151.                             if (cancelUpdate) {  
  152.                                 fos.write(buffer, 0, len);  
  153.                                 total += len;  
  154.                                 progress = (int) ((total / length) * 100);  
  155.                                 pbNewsDeatil.setProgress(progress);  
  156.                             }  
  157.                         }  
  158.                         in.close();  
  159.                         fos.close();  
  160.                     }  
  161.                 } catch (Exception e) {  
  162.                     e.printStackTrace();  
  163.                 }  
  164.                 // 进度达到最大值后,窗口消失  
  165.                 downloadDialog.cancel();  
  166.                 install();  
  167.             }  
  168.         }).start();  
  169.     }  
  170.   
  171.     private void install() {  
  172.         File file = new File(context.getFilesDir().getPath() + "/mynews.apk");  
  173.         Intent intent = new Intent(Intent.ACTION_VIEW);  
  174.   
  175.         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {  
  176.             intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);  
  177.             Uri contentUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".fileProvider", file);  
  178.             intent.setDataAndType(contentUri, "application/vnd.android.package-archive");  
  179.         } else {  
  180.             intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");  
  181.             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
  182.         }  
  183.         context.startActivity(intent);  
  184.     }  
  185. }  

在MainActivity的onCreate方法中调用

[java]  view plain  copy
  1. new Thread(new Runnable() {  
  2.            @Override  
  3.            public void run() {  
  4.                try {  
  5.                    String path = getResources().getString(R.string.issue) + "findVersion";  
  6.                    findVersion(path);  
  7.                } catch (Exception e) {  
  8.                    e.printStackTrace();  
  9.                }  
  10.            }  
  11.        }).start();  

[java]  view plain  copy
  1. /** 
  2.      * 查询版本信息 
  3.      * 
  4.      * @param path 
  5.      */  
  6.     private void findVersion(String path) {  
  7.         HttpClient httpClient = new DefaultHttpClient();  
  8.         HttpGet httpGet = new HttpGet(path);  
  9.         HttpResponse httpResponse;  
  10.         try {  
  11.             httpResponse = httpClient.execute(httpGet);  
  12.             if (httpResponse.getStatusLine().getStatusCode() == 200) {  
  13.                 HttpEntity entity = httpResponse.getEntity();  
  14.                 String result = EntityUtils.toString(entity, "utf-8");  
  15.                 JSONObject jsonObject = new JSONObject(result).getJSONObject("pd");  
  16.                 map = new HashMap<>();  
  17.                 map.put("VERSION_ID", jsonObject.getString("VERSION_ID"));  
  18.                 map.put("NUMBER", jsonObject.getString("NUMBER"));  
  19.                 map.put("CONTENT", jsonObject.getString("CONTENT"));  
  20.                 map.put("DATE", jsonObject.getString("DATE"));  
  21.                 map.put("STATUS", jsonObject.getString("STATUS"));  
  22.                 map.put("PATH", jsonObject.getString("PATH"));  
  23.                 handler.sendEmptyMessage(4);  //数据请求加载完毕发送消息让handler处理  
  24.             }  
  25.         } catch (Exception e) {  
  26.             e.printStackTrace();  
  27.         }  
  28.     }  
handler中进行处理
[java]  view plain  copy
  1. if (msg.what == 4) {  //版本更新的逻辑  
  2.                 VersionDao versionDao = new VersionDao(MainActivity.this, map);  
  3.                 versionDao.checkUpdate();  //更新操作  
  4.             }  

清单文件中配置

[html]  view plain  copy
  1. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  
  2.     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />  

[html]  view plain  copy
  1. <provider  
  2.            android:name="android.support.v4.content.FileProvider"  
  3.            android:authorities="com.mynews.fileProvider"  
  4.            android:exported="false"  
  5.            android:grantUriPermissions="true">  
  6.            <meta-data  
  7.                android:name="android.support.FILE_PROVIDER_PATHS"  
  8.                android:resource="@xml/file_paths" />  
  9.        </provider>  

res文件夹下新建xml文件夹,新建文件file_paths

[html]  view plain  copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <paths xmlns:android="http://schemas.android.com/apk/res/android">  
  3.     <files-path  
  4.         name="external_files"  
  5.         path="" />  
  6. </paths>  
运行程序查看效果




可能有一部分功能代码逻辑处理的并不是很好或是有BUG,还请各位多多包涵。小弟继续努力!

猜你喜欢

转载自blog.csdn.net/sinat_17775997/article/details/80737670