android小项目之新闻客户端三
基于Android的小巫新闻客户端开发--主界面业务逻辑实现
上一篇介绍了主界面的UI设计,现在直接进入主题,业务逻辑的实现,由于项目的开发总是在不断的完善的,最初实现的效果,总会随项目的进度而做出相应的改变,小巫也不可能从新开发整个客户端,然后再一步一步记录,那没有必要,学习东西,只需要知道关键点在哪里就行了,关于细节方面,遇到再去解决。就是这么简单。
主界面的最终实现效果如下;
下面是MainActivity.java的代码
- package com.xiaowu.news;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import org.json.JSONArray;
- import org.json.JSONObject;
- import android.app.Activity;
- import android.content.Intent;
- import android.graphics.Color;
- import android.graphics.drawable.ColorDrawable;
- import android.os.AsyncTask;
- import android.os.Bundle;
- import android.view.Gravity;
- import android.view.KeyEvent;
- import android.view.LayoutInflater;
- import android.view.Menu;
- import android.view.MenuItem;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.AdapterView;
- import android.widget.AdapterView.OnItemClickListener;
- import android.widget.Button;
- import android.widget.GridView;
- import android.widget.HorizontalScrollView;
- import android.widget.LinearLayout;
- import android.widget.LinearLayout.LayoutParams;
- import android.widget.ListView;
- import android.widget.ProgressBar;
- import android.widget.SimpleAdapter;
- import android.widget.TextView;
- import android.widget.Toast;
- import com.xiaowu.news.custom.ConstomSimpleAdapter;
- import com.xiaowu.news.model.Category;
- import com.xiaowu.news.service.SyncHttp;
- import com.xiaowu.news.update.UpdateManager;
- import com.xiaowu.news.util.DensityUtil;
- import com.xiaowu.news.util.StringUtil;
- /**
- *
- * @author wwj
- *
- */
- public class MainActivity extends Activity {
- private final int COLUMNWIDTH_PX = 56; // GridView每个单元格的宽度(像素)
- private final int FLINGVELOCITY_PX = 800; // ViewFilper滑动的距离(像素)
- private final int NEWSCOUNT = 5; // 显示新闻的条数
- private final int SUCCESS = 0; // 加载新闻成功
- private final int NONEWS = 1; // 没有新闻
- private final int NOMORENEWS = 2; // 没有更多新闻
- private final int LOADERROR = 3; // 加载失败
- private long exitTime; //按返回键退出的时间
- private int mColumnWidth_dip;
- private int mFlingVelocity_dip;
- private int mCid; // 新闻编号
- private String mCategoryTitle; // 新闻分类标题
- private ListView mNewslist; // 新闻列表
- private SimpleAdapter mNewslistAdapter; // 为新闻内容提供需要显示的列表
- private ArrayList<HashMap<String, Object>> mNewsData; // 存储新闻信息的数据集合
- private LayoutInflater mInflater; // 用来动态载入没有loadmore_layout界面
- private Button category_Button = null; // 新闻分类标题栏的向右查看的按钮
- private HorizontalScrollView categoryScrollView = null;// 水平滚动图
- private Button mTitleBarRefresh; // 标题栏的刷新按钮
- private ProgressBar mTitleBarProgress; // 进度条
- private Button mLoadmoreButton; // 加载更多按钮
- private LoadNewsAsyncTack mLoadNewsAsyncTack; // 声明LoadNewsAsyncTack引用
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.news_home_layout);
- //通过id来获取按钮的引用
- mTitleBarRefresh = (Button) findViewById(R.id.titlebar_refresh);
- mTitleBarProgress = (ProgressBar) findViewById(R.id.titlebar_progress);
- mTitleBarRefresh.setOnClickListener(loadmoreListener);
- // 将px转换为dip
- mColumnWidth_dip = DensityUtil.px2dip(this, COLUMNWIDTH_PX);
- mFlingVelocity_dip = DensityUtil.px2dip(this, FLINGVELOCITY_PX);
- //初始化新闻分类的编号
- mCid = 1;
- mCategoryTitle = "焦点";
- mInflater = getLayoutInflater();
- //存储新闻信息的数据集合
- mNewsData = new ArrayList<HashMap<String, Object>>();
- // 获取数组资源
- String[] categoryArray = getResources().getStringArray(
- R.array.categories);
- // 定义一个List数组,用来存放HashMap对象
- final List<HashMap<String, Category>> categories = new ArrayList<HashMap<String, Category>>();
- // 分割新闻字符串
- for (int i = 0; i < categoryArray.length; i++) {
- String temp[] = categoryArray[i].split("[|]");
- if (temp.length == 2) {
- int cid = StringUtil.string2Int(temp[0]);
- String title = temp[1];
- Category type = new Category(cid, title);
- // 定义一个HashMap对象,用来存放键值对
- HashMap<String, Category> hashMap = new HashMap<String, Category>();
- hashMap.put("category_title", type);
- categories.add(hashMap);
- }
- }
- ConstomSimpleAdapter categoryAdapter = new ConstomSimpleAdapter(this,
- categories, R.layout.category_item_layout,
- new String[] { "category_title" },
- new int[] { R.id.category_title });
- // 创建一个网格视图, 用于实现新闻标题的布局
- GridView category = new GridView(this);
- // 设置单元格的背景色为透明,这样选择分类时就不会显示黄色背景了
- category.setSelector(new ColorDrawable(Color.TRANSPARENT));
- // 设置每一个新闻标题的宽度
- category.setColumnWidth(mColumnWidth_dip);
- // 设置网格视图的列数
- category.setNumColumns(GridView.AUTO_FIT);
- // 设置对齐方式
- category.setGravity(Gravity.CENTER);
- // 根据单元格的宽度和数目计算网格视图的宽度
- int width = mColumnWidth_dip * categories.size();
- // 获取布局参数
- LayoutParams params = new LayoutParams(width, LayoutParams.MATCH_PARENT);
- // 设置参数
- category.setLayoutParams(params);
- // 设置Adapter
- category.setAdapter(categoryAdapter);
- // 通过ID获取LinearLayout布局对象
- LinearLayout categoryLayout = (LinearLayout) findViewById(R.id.category_layout);
- // 将网格视图组件添加到LinearLayout布局当中
- categoryLayout.addView(category);
- // 添加单元格点击事件
- category.setOnItemClickListener(new OnItemClickListener() {
- TextView categoryTitle;
- @Override
- public void onItemClick(AdapterView<?> parent, View view,
- int position, long id) {
- // TODO Auto-generated method stub
- for (int i = 0; i < parent.getCount(); i++) {
- categoryTitle = (TextView) parent.getChildAt(i);
- categoryTitle.setTextColor(0XFFADB2AD);
- categoryTitle.setBackgroundDrawable(null);
- }
- categoryTitle = (TextView) view;
- categoryTitle.setTextColor(0xFFFFFFFF);
- categoryTitle
- .setBackgroundResource(R.drawable.image_categorybar_item_selected_background);
- Toast.makeText(MainActivity.this, categoryTitle.getText(),
- Toast.LENGTH_SHORT).show();
- //获取新闻分类编号
- mCid = categories.get(position).get("category_title").getCid();
- mCategoryTitle = categories.get(position).get("category_title").getTitle();
- mLoadNewsAsyncTack = new LoadNewsAsyncTack();
- mLoadNewsAsyncTack.execute(0, true);
- }
- });
- //第一次获取新闻列表
- getSpecCatNews(mCid, mNewsData, 0, true);
- // 箭头
- categoryScrollView = (HorizontalScrollView) findViewById(R.id.categorybar_scrollView);
- category_Button = (Button) findViewById(R.id.category_arrow_right);
- category_Button.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- categoryScrollView.fling(mFlingVelocity_dip);
- }
- });
- mNewslistAdapter = new SimpleAdapter(this, mNewsData,
- R.layout.newslist_item_layout, new String[] {
- "newslist_item_title", "newslist_item_digest",
- "newslist_item_source", "newslist_item_ptime" },
- new int[] { R.id.newslist_item_title,
- R.id.newslist_item_digest, R.id.newslist_item_source,
- R.id.newslist_item_ptime });
- mNewslist = (ListView) findViewById(R.id.news_list);
- View footerView = mInflater.inflate(R.layout.loadmore_layout, null);
- //在LiseView下面添加“加载更多”
- mNewslist.addFooterView(footerView);
- //显示列表
- mNewslist.setAdapter(mNewslistAdapter);
- mNewslist.setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View view,
- int position, long id) {
- // TODO Auto-generated method stub
- Intent intent = new Intent(MainActivity.this,
- NewsDetailActivity.class);
- intent.putExtra("categoryTitle", mCategoryTitle);
- intent.putExtra("newsData", mNewsData);
- intent.putExtra("position", position);
- startActivity(intent);
- }
- });
- mLoadmoreButton = (Button) findViewById(R.id.loadmore_btn);
- mLoadmoreButton.setOnClickListener(loadmoreListener);
- }
- /**
- * 获取指定类型的新闻列表
- *
- * @param cid
- * @return
- */
- private int getSpecCatNews(int cid, List<HashMap<String, Object>> newsList,
- int startnid, boolean firstTime) {
- // 如果是第一次加载的话
- if (firstTime) {
- newsList.clear();
- }
- //本机:http://10.0.2.2:8080/web/getSpecifyCategoryNews
- //wifi局域网:192.168.220.1
- String url = "http://10.0.2.2:8080/web/getSpecifyCategoryNews";
- String params = "startnid=" + startnid + "&count=" + NEWSCOUNT
- + "&cid=" + cid;
- SyncHttp syncHttp = new SyncHttp();
- try {
- // 通过Http协议发送Get请求,返回字符串
- String retStr = syncHttp.httpGet(url, params);
- JSONObject jsonObject = new JSONObject(retStr);
- int retCode = jsonObject.getInt("ret");
- if (retCode == 0) {
- JSONObject dataObj = jsonObject.getJSONObject("data");
- // 获取返回数目
- int totalNum = dataObj.getInt("totalnum");
- if (totalNum > 0) {
- // 获取返回新闻集合
- JSONArray newslistArray = dataObj.getJSONArray("newslist");
- // 将用JSON格式解析的数据添加到数据集合当中
- for (int i = 0; i < newslistArray.length(); i++) {
- JSONObject newsObject = (JSONObject) newslistArray
- .opt(i);
- HashMap<String, Object> hashMap = new HashMap<String, Object>();
- hashMap.put("nid", newsObject.getInt("nid"));
- hashMap.put("newslist_item_title",
- newsObject.getString("title"));
- hashMap.put("newslist_item_digest",
- newsObject.getString("digest"));
- hashMap.put("newslist_item_source",
- newsObject.getString("source"));
- hashMap.put("newslist_item_ptime",
- newsObject.getString("ptime"));
- hashMap.put("newslist_item_comments",
- newsObject.getInt("commentcount"));
- newsList.add(hashMap);
- }
- return SUCCESS;
- } else {
- //第一次加载新闻列表
- if (firstTime) {
- return NONEWS; //没有新闻
- } else {
- return NOMORENEWS; //没有更多新闻
- }
- }
- } else {
- return LOADERROR; //加载新闻失败
- }
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- return LOADERROR; //加载新闻失败
- }
- }
- /**
- * 为“加载更多”按钮定义匿名内部类
- */
- private OnClickListener loadmoreListener = new OnClickListener() {
- @Override
- public void onClick(View v) {
- mLoadNewsAsyncTack = new LoadNewsAsyncTack();
- switch (v.getId()) {
- //点击加载更多
- case R.id.loadmore_btn:
- mLoadNewsAsyncTack.execute(mNewsData.size(), false); //不是第一次加载新闻里列表
- break;
- //点击刷新按钮
- case R.id.titlebar_refresh:
- mLoadNewsAsyncTack.execute(0, true);
- break;
- }
- }
- };
- /**
- * 异步更新UI
- * @author wwj
- *
- */
- private class LoadNewsAsyncTack extends AsyncTask<Object, Integer, Integer> {
- //准备运行
- @Override
- protected void onPreExecute() {
- mTitleBarRefresh.setVisibility(View.GONE);
- mTitleBarProgress.setVisibility(View.VISIBLE);
- mLoadmoreButton.setText(R.string.loadmore_text);
- }
- //在后台运行
- @Override
- protected Integer doInBackground(Object... params) {
- return getSpecCatNews(mCid, mNewsData, (Integer) params[0],
- (Boolean) params[1]);
- }
- //完成后台任务
- @Override
- protected void onPostExecute(Integer result) {
- switch (result) {
- //该栏目没有新闻
- case NONEWS:
- Toast.makeText(MainActivity.this, R.string.nonews, Toast.LENGTH_SHORT)
- .show();
- break;
- //该栏目没有更多新闻
- case NOMORENEWS:
- Toast.makeText(MainActivity.this, R.string.nomorenews,
- Toast.LENGTH_SHORT).show();
- break;
- //加载失败
- case LOADERROR:
- Toast.makeText(MainActivity.this, R.string.loadnewserror, Toast.LENGTH_SHORT)
- .show();
- break;
- }
- mTitleBarRefresh.setVisibility(View.VISIBLE); //刷新按钮设置为可见
- mTitleBarProgress.setVisibility(View.GONE); //进度条设置为不可见
- mLoadmoreButton.setText(R.string.loadmore_btn); //按钮信息替换为“加载更多”
- mNewslistAdapter.notifyDataSetChanged(); //通知ListView更新数据
- }
- }
- /**
- * 添加菜单
- */
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // TODO Auto-generated method stub
- menu.add(1, 1, 1, "更新");
- menu.add(1, 2, 2, "退出");
- return true;
- }
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch(item.getItemId()) {
- case 1:
- UpdateManager updateManager = new UpdateManager(MainActivity.this);
- //检测更新
- updateManager.checkUpdate();
- break;
- case 2:
- finish();
- break;
- }
- return true;
- }
- /**
- * 按键触发的事件
- */
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if(keyCode == KeyEvent.KEYCODE_BACK
- && event.getAction() == KeyEvent.ACTION_DOWN){
- if((System.currentTimeMillis() - exitTime > 2000)){
- Toast.makeText(getApplicationContext(), R.string.backcancel
- , Toast.LENGTH_LONG).show();
- exitTime = System.currentTimeMillis();
- }
- else{
- finish();
- System.exit(0);
- }
- return true;
- }
- return super.onKeyDown(keyCode, event);
- }
- }
package com.xiaowu.news;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.GridView;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
import com.xiaowu.news.custom.ConstomSimpleAdapter;
import com.xiaowu.news.model.Category;
import com.xiaowu.news.service.SyncHttp;
import com.xiaowu.news.update.UpdateManager;
import com.xiaowu.news.util.DensityUtil;
import com.xiaowu.news.util.StringUtil;
/**
*
* @author wwj
*
*/
public class MainActivity extends Activity {
private final int COLUMNWIDTH_PX = 56; // GridView每个单元格的宽度(像素)
private final int FLINGVELOCITY_PX = 800; // ViewFilper滑动的距离(像素)
private final int NEWSCOUNT = 5; // 显示新闻的条数
private final int SUCCESS = 0; // 加载新闻成功
private final int NONEWS = 1; // 没有新闻
private final int NOMORENEWS = 2; // 没有更多新闻
private final int LOADERROR = 3; // 加载失败
private long exitTime; //按返回键退出的时间
private int mColumnWidth_dip;
private int mFlingVelocity_dip;
private int mCid; // 新闻编号
private String mCategoryTitle; // 新闻分类标题
private ListView mNewslist; // 新闻列表
private SimpleAdapter mNewslistAdapter; // 为新闻内容提供需要显示的列表
private ArrayList<HashMap<String, Object>> mNewsData; // 存储新闻信息的数据集合
private LayoutInflater mInflater; // 用来动态载入没有loadmore_layout界面
private Button category_Button = null; // 新闻分类标题栏的向右查看的按钮
private HorizontalScrollView categoryScrollView = null;// 水平滚动图
private Button mTitleBarRefresh; // 标题栏的刷新按钮
private ProgressBar mTitleBarProgress; // 进度条
private Button mLoadmoreButton; // 加载更多按钮
private LoadNewsAsyncTack mLoadNewsAsyncTack; // 声明LoadNewsAsyncTack引用
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news_home_layout);
//通过id来获取按钮的引用
mTitleBarRefresh = (Button) findViewById(R.id.titlebar_refresh);
mTitleBarProgress = (ProgressBar) findViewById(R.id.titlebar_progress);
mTitleBarRefresh.setOnClickListener(loadmoreListener);
// 将px转换为dip
mColumnWidth_dip = DensityUtil.px2dip(this, COLUMNWIDTH_PX);
mFlingVelocity_dip = DensityUtil.px2dip(this, FLINGVELOCITY_PX);
//初始化新闻分类的编号
mCid = 1;
mCategoryTitle = "焦点";
mInflater = getLayoutInflater();
//存储新闻信息的数据集合
mNewsData = new ArrayList<HashMap<String, Object>>();
// 获取数组资源
String[] categoryArray = getResources().getStringArray(
R.array.categories);
// 定义一个List数组,用来存放HashMap对象
final List<HashMap<String, Category>> categories = new ArrayList<HashMap<String, Category>>();
// 分割新闻字符串
for (int i = 0; i < categoryArray.length; i++) {
String temp[] = categoryArray[i].split("[|]");
if (temp.length == 2) {
int cid = StringUtil.string2Int(temp[0]);
String title = temp[1];
Category type = new Category(cid, title);
// 定义一个HashMap对象,用来存放键值对
HashMap<String, Category> hashMap = new HashMap<String, Category>();
hashMap.put("category_title", type);
categories.add(hashMap);
}
}
ConstomSimpleAdapter categoryAdapter = new ConstomSimpleAdapter(this,
categories, R.layout.category_item_layout,
new String[] { "category_title" },
new int[] { R.id.category_title });
// 创建一个网格视图, 用于实现新闻标题的布局
GridView category = new GridView(this);
// 设置单元格的背景色为透明,这样选择分类时就不会显示黄色背景了
category.setSelector(new ColorDrawable(Color.TRANSPARENT));
// 设置每一个新闻标题的宽度
category.setColumnWidth(mColumnWidth_dip);
// 设置网格视图的列数
category.setNumColumns(GridView.AUTO_FIT);
// 设置对齐方式
category.setGravity(Gravity.CENTER);
// 根据单元格的宽度和数目计算网格视图的宽度
int width = mColumnWidth_dip * categories.size();
// 获取布局参数
LayoutParams params = new LayoutParams(width, LayoutParams.MATCH_PARENT);
// 设置参数
category.setLayoutParams(params);
// 设置Adapter
category.setAdapter(categoryAdapter);
// 通过ID获取LinearLayout布局对象
LinearLayout categoryLayout = (LinearLayout) findViewById(R.id.category_layout);
// 将网格视图组件添加到LinearLayout布局当中
categoryLayout.addView(category);
// 添加单元格点击事件
category.setOnItemClickListener(new OnItemClickListener() {
TextView categoryTitle;
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
for (int i = 0; i < parent.getCount(); i++) {
categoryTitle = (TextView) parent.getChildAt(i);
categoryTitle.setTextColor(0XFFADB2AD);
categoryTitle.setBackgroundDrawable(null);
}
categoryTitle = (TextView) view;
categoryTitle.setTextColor(0xFFFFFFFF);
categoryTitle
.setBackgroundResource(R.drawable.image_categorybar_item_selected_background);
Toast.makeText(MainActivity.this, categoryTitle.getText(),
Toast.LENGTH_SHORT).show();
//获取新闻分类编号
mCid = categories.get(position).get("category_title").getCid();
mCategoryTitle = categories.get(position).get("category_title").getTitle();
mLoadNewsAsyncTack = new LoadNewsAsyncTack();
mLoadNewsAsyncTack.execute(0, true);
}
});
//第一次获取新闻列表
getSpecCatNews(mCid, mNewsData, 0, true);
// 箭头
categoryScrollView = (HorizontalScrollView) findViewById(R.id.categorybar_scrollView);
category_Button = (Button) findViewById(R.id.category_arrow_right);
category_Button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
categoryScrollView.fling(mFlingVelocity_dip);
}
});
mNewslistAdapter = new SimpleAdapter(this, mNewsData,
R.layout.newslist_item_layout, new String[] {
"newslist_item_title", "newslist_item_digest",
"newslist_item_source", "newslist_item_ptime" },
new int[] { R.id.newslist_item_title,
R.id.newslist_item_digest, R.id.newslist_item_source,
R.id.newslist_item_ptime });
mNewslist = (ListView) findViewById(R.id.news_list);
View footerView = mInflater.inflate(R.layout.loadmore_layout, null);
//在LiseView下面添加“加载更多”
mNewslist.addFooterView(footerView);
//显示列表
mNewslist.setAdapter(mNewslistAdapter);
mNewslist.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
Intent intent = new Intent(MainActivity.this,
NewsDetailActivity.class);
intent.putExtra("categoryTitle", mCategoryTitle);
intent.putExtra("newsData", mNewsData);
intent.putExtra("position", position);
startActivity(intent);
}
});
mLoadmoreButton = (Button) findViewById(R.id.loadmore_btn);
mLoadmoreButton.setOnClickListener(loadmoreListener);
}
/**
* 获取指定类型的新闻列表
*
* @param cid
* @return
*/
private int getSpecCatNews(int cid, List<HashMap<String, Object>> newsList,
int startnid, boolean firstTime) {
// 如果是第一次加载的话
if (firstTime) {
newsList.clear();
}
//本机:http://10.0.2.2:8080/web/getSpecifyCategoryNews
//wifi局域网:192.168.220.1
String url = "http://10.0.2.2:8080/web/getSpecifyCategoryNews";
String params = "startnid=" + startnid + "&count=" + NEWSCOUNT
+ "&cid=" + cid;
SyncHttp syncHttp = new SyncHttp();
try {
// 通过Http协议发送Get请求,返回字符串
String retStr = syncHttp.httpGet(url, params);
JSONObject jsonObject = new JSONObject(retStr);
int retCode = jsonObject.getInt("ret");
if (retCode == 0) {
JSONObject dataObj = jsonObject.getJSONObject("data");
// 获取返回数目
int totalNum = dataObj.getInt("totalnum");
if (totalNum > 0) {
// 获取返回新闻集合
JSONArray newslistArray = dataObj.getJSONArray("newslist");
// 将用JSON格式解析的数据添加到数据集合当中
for (int i = 0; i < newslistArray.length(); i++) {
JSONObject newsObject = (JSONObject) newslistArray
.opt(i);
HashMap<String, Object> hashMap = new HashMap<String, Object>();
hashMap.put("nid", newsObject.getInt("nid"));
hashMap.put("newslist_item_title",
newsObject.getString("title"));
hashMap.put("newslist_item_digest",
newsObject.getString("digest"));
hashMap.put("newslist_item_source",
newsObject.getString("source"));
hashMap.put("newslist_item_ptime",
newsObject.getString("ptime"));
hashMap.put("newslist_item_comments",
newsObject.getInt("commentcount"));
newsList.add(hashMap);
}
return SUCCESS;
} else {
//第一次加载新闻列表
if (firstTime) {
return NONEWS; //没有新闻
} else {
return NOMORENEWS; //没有更多新闻
}
}
} else {
return LOADERROR; //加载新闻失败
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return LOADERROR; //加载新闻失败
}
}
/**
* 为“加载更多”按钮定义匿名内部类
*/
private OnClickListener loadmoreListener = new OnClickListener() {
@Override
public void onClick(View v) {
mLoadNewsAsyncTack = new LoadNewsAsyncTack();
switch (v.getId()) {
//点击加载更多
case R.id.loadmore_btn:
mLoadNewsAsyncTack.execute(mNewsData.size(), false); //不是第一次加载新闻里列表
break;
//点击刷新按钮
case R.id.titlebar_refresh:
mLoadNewsAsyncTack.execute(0, true);
break;
}
}
};
/**
* 异步更新UI
* @author wwj
*
*/
private class LoadNewsAsyncTack extends AsyncTask<Object, Integer, Integer> {
//准备运行
@Override
protected void onPreExecute() {
mTitleBarRefresh.setVisibility(View.GONE);
mTitleBarProgress.setVisibility(View.VISIBLE);
mLoadmoreButton.setText(R.string.loadmore_text);
}
//在后台运行
@Override
protected Integer doInBackground(Object... params) {
return getSpecCatNews(mCid, mNewsData, (Integer) params[0],
(Boolean) params[1]);
}
//完成后台任务
@Override
protected void onPostExecute(Integer result) {
switch (result) {
//该栏目没有新闻
case NONEWS:
Toast.makeText(MainActivity.this, R.string.nonews, Toast.LENGTH_SHORT)
.show();
break;
//该栏目没有更多新闻
case NOMORENEWS:
Toast.makeText(MainActivity.this, R.string.nomorenews,
Toast.LENGTH_SHORT).show();
break;
//加载失败
case LOADERROR:
Toast.makeText(MainActivity.this, R.string.loadnewserror, Toast.LENGTH_SHORT)
.show();
break;
}
mTitleBarRefresh.setVisibility(View.VISIBLE); //刷新按钮设置为可见
mTitleBarProgress.setVisibility(View.GONE); //进度条设置为不可见
mLoadmoreButton.setText(R.string.loadmore_btn); //按钮信息替换为“加载更多”
mNewslistAdapter.notifyDataSetChanged(); //通知ListView更新数据
}
}
/**
* 添加菜单
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
menu.add(1, 1, 1, "更新");
menu.add(1, 2, 2, "退出");
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case 1:
UpdateManager updateManager = new UpdateManager(MainActivity.this);
//检测更新
updateManager.checkUpdate();
break;
case 2:
finish();
break;
}
return true;
}
/**
* 按键触发的事件
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK
&& event.getAction() == KeyEvent.ACTION_DOWN){
if((System.currentTimeMillis() - exitTime > 2000)){
Toast.makeText(getApplicationContext(), R.string.backcancel
, Toast.LENGTH_LONG).show();
exitTime = System.currentTimeMillis();
}
else{
finish();
System.exit(0);
}
return true;
}
return super.onKeyDown(keyCode, event);
}
}
主界面的业务逻辑实现,要一步就实现是非常困难的,因为项目总是从简单到复杂,所以小巫只把关键点说一下就行了:
这里主要有三个关键点:
1.分类栏的实现?
首先创建一个GridView视图,通过GridView来填充数据,把每一类新闻分类显示到GridView视图中去,最后通过获取到界面布局中的LinearLayout对象,把GridView添加到LinearLayout布局当中去,最终实现效果。
2.获取新闻分类列表(对JSON格式数据的解析)?
JSON数据的解析并不算太难,主要把JSON数据的数据结构搞清楚,解析起来还是挺方便的。
进行解析虽然方便,但前提是要把数据得到,因为数据是要在服务器端得到,需要利用Android的Http通信来实现。
这里需要利用到httpGet还有httpPost方法,这个代码很需要贴一贴滴。自定义的SyncHttp类
- package com.xiaowu.news.service;
- import java.util.ArrayList;
- import java.util.List;
- import org.apache.http.HttpResponse;
- import org.apache.http.HttpStatus;
- import org.apache.http.client.HttpClient;
- import org.apache.http.client.entity.UrlEncodedFormEntity;
- import org.apache.http.client.methods.HttpGet;
- import org.apache.http.client.methods.HttpPost;
- import org.apache.http.impl.client.DefaultHttpClient;
- import org.apache.http.message.BasicNameValuePair;
- import org.apache.http.params.BasicHttpParams;
- import org.apache.http.params.HttpConnectionParams;
- import org.apache.http.params.HttpParams;
- import org.apache.http.protocol.HTTP;
- import org.apache.http.util.EntityUtils;
- import com.xiaowu.news.model.Parameter;
- public class SyncHttp {
- /**
- * 通过Get方式发送请求
- * @param url
- * @param params
- * @return
- * @throws Exception
- */
- public String httpGet(String url, String params) throws Exception {
- String response = null; //返回信息
- //拼接请求URl
- if(null != params && !params.equals("")) {
- url += "?" + params;
- }
- int timeOutConnection = 3000;
- int timeOutSocket = 5000;
- HttpParams httpParams = new BasicHttpParams();
- HttpConnectionParams.setConnectionTimeout(httpParams, timeOutConnection);
- HttpConnectionParams.setSoTimeout(httpParams, timeOutSocket);
- //构造HttpClient实例
- HttpClient httpClient = new DefaultHttpClient();
- //创建GET方法实例
- HttpGet httpGet = new HttpGet(url);
- try {
- HttpResponse httpResponse = httpClient.execute(httpGet);
- int statusCode = httpResponse.getStatusLine().getStatusCode();
- if(statusCode == HttpStatus.SC_OK) {
- //获得返回结果
- response = EntityUtils.toString(httpResponse.getEntity());
- }
- else{
- response = "返回码:" + statusCode;
- }
- } catch (Exception e) {
- // TODO: handle exception
- throw new Exception(e);
- }
- return response;
- }
- /**
- * 通过post方式发送请求
- * @param url
- * @param params
- * @return
- * @throws Exception
- */
- public String httpPost(String url, List<Parameter> params) throws Exception {
- String response = null;
- int timeOutConnection = 3000;
- int timeOutSocket = 5000;
- HttpParams httpParams = new BasicHttpParams();
- HttpConnectionParams.setConnectionTimeout(httpParams, timeOutConnection);
- HttpConnectionParams.setSoTimeout(httpParams, timeOutSocket);
- //构造HttpClient实例
- HttpClient httpClient = new DefaultHttpClient();
- HttpPost httpPost = new HttpPost(url);
- if(params.size() > 0) {
- //设置post请求参数
- httpPost.setEntity(new UrlEncodedFormEntity(buildNameValuePair(params), HTTP.UTF_8));
- }
- //使用execute方法发送Http Post 请求,并返回HttpResponse对象
- HttpResponse httpResponse = httpClient.execute(httpPost);
- int statusCode = httpResponse.getStatusLine().getStatusCode();
- if(statusCode == HttpStatus.SC_OK) {
- //获得返回结果
- response = EntityUtils.toString(httpResponse.getEntity());
- }
- else {
- response = "返回码:" + statusCode;
- }
- return response;
- }
- /**
- * 把Paramster类型集合转换为NameValuePair类型集合
- * @param params
- * @return
- */
- private List<BasicNameValuePair> buildNameValuePair (List<Parameter> params) {
- List<BasicNameValuePair> result = new ArrayList<BasicNameValuePair>();
- for(Parameter param : params) {
- BasicNameValuePair pair = new BasicNameValuePair(param.getName(), param.getValue());
- result.add(pair);
- }
- return result;
- }
- }
package com.xiaowu.news.service;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import com.xiaowu.news.model.Parameter;
public class SyncHttp {
/**
* 通过Get方式发送请求
* @param url
* @param params
* @return
* @throws Exception
*/
public String httpGet(String url, String params) throws Exception {
String response = null; //返回信息
//拼接请求URl
if(null != params && !params.equals("")) {
url += "?" + params;
}
int timeOutConnection = 3000;
int timeOutSocket = 5000;
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, timeOutConnection);
HttpConnectionParams.setSoTimeout(httpParams, timeOutSocket);
//构造HttpClient实例
HttpClient httpClient = new DefaultHttpClient();
//创建GET方法实例
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse httpResponse = httpClient.execute(httpGet);
int statusCode = httpResponse.getStatusLine().getStatusCode();
if(statusCode == HttpStatus.SC_OK) {
//获得返回结果
response = EntityUtils.toString(httpResponse.getEntity());
}
else{
response = "返回码:" + statusCode;
}
} catch (Exception e) {
// TODO: handle exception
throw new Exception(e);
}
return response;
}
/**
* 通过post方式发送请求
* @param url
* @param params
* @return
* @throws Exception
*/
public String httpPost(String url, List<Parameter> params) throws Exception {
String response = null;
int timeOutConnection = 3000;
int timeOutSocket = 5000;
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, timeOutConnection);
HttpConnectionParams.setSoTimeout(httpParams, timeOutSocket);
//构造HttpClient实例
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
if(params.size() > 0) {
//设置post请求参数
httpPost.setEntity(new UrlEncodedFormEntity(buildNameValuePair(params), HTTP.UTF_8));
}
//使用execute方法发送Http Post 请求,并返回HttpResponse对象
HttpResponse httpResponse = httpClient.execute(httpPost);
int statusCode = httpResponse.getStatusLine().getStatusCode();
if(statusCode == HttpStatus.SC_OK) {
//获得返回结果
response = EntityUtils.toString(httpResponse.getEntity());
}
else {
response = "返回码:" + statusCode;
}
return response;
}
/**
* 把Paramster类型集合转换为NameValuePair类型集合
* @param params
* @return
*/
private List<BasicNameValuePair> buildNameValuePair (List<Parameter> params) {
List<BasicNameValuePair> result = new ArrayList<BasicNameValuePair>();
for(Parameter param : params) {
BasicNameValuePair pair = new BasicNameValuePair(param.getName(), param.getValue());
result.add(pair);
}
return result;
}
}
定义好了SyncHttp类之后,就可以通过调用httpGet方法来获取数据,在Activity的getSpecCatNews方法有详细实现,看一下就可以知道了。
3.异步更新UI的实现?
关于异步更新UI也算是一个比较难理解的东西,在Activity里定义了一个继承AsyncTask类的内部类,并实现三个方法,比较灵活。具体实现看代码。
以上三点是小巫认为比较核心的地方,具体的需要动手之后才知道。
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。