安卓listView下拉刷新,已读未读状态以及SQLite做本地缓存,详细介绍
2014-03-19 17:24
543 查看
说说下拉刷新:
下拉刷新头文件的布局:pulllist-head.xml
首次登录进来SQLite里面没有数据,需手动点击请求网络加载:
之后就可以下拉刷新了:
<?xml version="1.0" encoding="utf-8"?>
<!-- ListView的头部 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:background="#FFFFFFFF" >
<!-- 内容 -->
<RelativeLayout
android:id="@+id/head_contentLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:paddingLeft="10dp" >
<!-- 箭头图像、进度条 -->
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true" >
<!-- 箭头 -->
<ImageView
android:id="@+id/head_arrowImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/pulltorefresh" />
<!-- 进度条 -->
<ProgressBar
android:id="@+id/head_progressBar"
style="@android:style/Widget.ProgressBar.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
</FrameLayout>
<!-- 提示、最近更新 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:gravity="center_horizontal"
android:orientation="vertical" >
<!-- 提示 -->
<TextView
android:id="@+id/head_tipsTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp" />
<!-- 最近更新 -->
<TextView
android:id="@+id/head_lastUpdatedTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="13sp" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
主页面布局文件:notice-activity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff">
<LinearLayout android:id="@+id/doc_isnull"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/empty_view"
>
</ImageView>
</LinearLayout>
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content">
//listview 注意前面路径一定要写对 否则会报错,小五就犯过这个低级错误
<com.example.SQLite.RTPullListView android:id="@+id/noticelistview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginRight="3dp"
android:layout_marginLeft="3dp"
android:focusable="true"
android:divider="@null"
android:cacheColorHint="#00000000"/>
</LinearLayout>
</LinearLayout>
listview里面的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:focusableInTouchMode="false"
android:layout_height="60dp">
<ImageView
android:layout_width="fill_parent"
android:layout_height="1dp"
android:background="#cccccc">
</ImageView>
<LinearLayout android:layout_width="fill_parent"
android:layout_height="59dp"
android:focusableInTouchMode="false"
android:background="#ffffff"
android:orientation="vertical">
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:focusable="false"
android:layout_marginTop="5dp"
android:orientation="horizontal">
<LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:focusable="false"
android:layout_marginLeft="10dp"
android:background="@drawable/notice_status">
<TextView android:id="@+id/mark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:layout_marginLeft="10dp"
android:gravity="left"
android:focusable="false"
android:layout_marginRight="10dp"
android:textColor="#B71C00"
android:text=""/>
</LinearLayout>
<TextView android:id="@+id/titleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginLeft="10dp"
android:focusable="false"
android:layout_weight="1"
android:textColor="@color/black"
android:textSize="15dp"
android:singleLine="true"
android:text=""/>
<ImageView android:id="@+id/mark"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginRight="10dp"
android:layout_marginTop="5dp"
android:focusable="false"
android:layout_gravity="center_vertical"
android:background="@drawable/arrows"/>
</LinearLayout>
<LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false">
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="70dp"
android:focusable="false"
android:layout_marginTop="3dp"
android:background="@drawable/timeicon"/>
<TextView android:id="@+id/dataTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:focusable="false"
android:textColor="@color/TimeColor"
android:text=""/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
listview点击进去布局文件:myactivity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg4">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我进来了"
android:layout_gravity="center"
android:layout_marginTop="100dp"
android:textColor="@color/black"
android:textSize="40dp"/>
</LinearLayout>
java代码DBHelper.java
这个类是用来在SQLite中创建表
package com.example.SQLite;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.AssetManager;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DBHelper extends SQLiteOpenHelper {
private static DBHelper dbHelper;
private static int version = 1;
private Context context;
private SQLiteDatabase db;
public DBHelper(Context context) {
super(context, "sqlitedemo", null, version);
this.context = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
this.db = db;
try {
initDB();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
public static synchronized void init(Context context) throws NameNotFoundException {
if (dbHelper == null) {
dbHelper = new DBHelper(context);
}
}
public static SQLiteDatabase getDB() {
return dbHelper.getWritableDatabase();
}
private void initDB() throws IOException {
AssetManager assetManager = context.getAssets();
InputStream inStream = assetManager.open("notice_sql.sql");
BufferedReader reader = new BufferedReader(new InputStreamReader(
inStream));
StringBuffer sql = new StringBuffer();
String line = null;
while ((line = reader.readLine()) != null) {
sql.append(line);
}
reader.close();
Log.d("SQLite", "Init db " + sql.toString());
db.execSQL(sql.toString());
Log.i("SQLite", "Init database");
}
public SQLiteDatabase getDb() {
return db;
}
}
下拉刷新的类:RTPullListView.java
package com.example.SQLite;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.*;
import android.widget.AbsListView.OnScrollListener;
import java.util.Date;
public class RTPullListView extends ListView implements OnScrollListener {
private static final String TAG = "RTPullListView";
private final static int RELEASE_To_REFRESH = 0;
private final static int PULL_To_REFRESH = 1;
private final static int REFRESHING = 2;
private final static int DONE = 3;
private final static int LOADING = 4;
// 实际的padding的距离与界面上偏移距离的比例
private final static int RATIO = 3;
private LayoutInflater inflater;
private LinearLayout headView;
private TextView tipsTextview;
private TextView lastUpdatedTextView;
private ImageView arrowImageView;
private ProgressBar progressBar;
private RotateAnimation animation;
private RotateAnimation reverseAnimation;
// 用于保证startY的值在一个完整的touch事件中只被记录一次
private boolean isRecored;
private int headContentHeight;
private int startY;
private int firstItemIndex;
private int state;
private boolean isBack;
private OnRefreshListener refreshListener;
private boolean isRefreshable;
private boolean isPush;
private int visibleLastIndex;
private int visibleItemCount;
public RTPullListView(Context context) {
super(context);
init(context);
}
public RTPullListView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
inflater = LayoutInflater.from(context);
headView = (LinearLayout) inflater.inflate(R.layout.pulllist_head, null);
arrowImageView = (ImageView) headView.findViewById(R.id.head_arrowImageView);
//arrowImageView.setMinimumWidth(70);
//arrowImageView.setMinimumHeight(50);
progressBar = (ProgressBar) headView.findViewById(R.id.head_progressBar);
tipsTextview = (TextView) headView.findViewById(R.id.head_tipsTextView);
lastUpdatedTextView = (TextView) headView.findViewById(R.id.head_lastUpdatedTextView);
measureView(headView);
headContentHeight = headView.getMeasuredHeight();
//headContentWidth = headView.getMeasuredWidth();
headView.setPadding(0, -1 * headContentHeight, 0, 0);
headView.invalidate();
addHeaderView(headView, null, false);
setOnScrollListener(this);
animation = new RotateAnimation(0, -180,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
animation.setInterpolator(new LinearInterpolator());
animation.setDuration(250);
animation.setFillAfter(true);
reverseAnimation = new RotateAnimation(-180, 0,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
reverseAnimation.setInterpolator(new LinearInterpolator());
reverseAnimation.setDuration(200);
reverseAnimation.setFillAfter(true);
state = DONE;
isRefreshable = false;
isPush = true;
}
public void onScroll(AbsListView arg0, int firstVisiableItem, int arg2,
int arg3) {
firstItemIndex = firstVisiableItem;
visibleLastIndex = firstVisiableItem + arg2 - 1;
visibleItemCount = arg2;
if(firstItemIndex == 1 && !isPush){
setSelection(0);
}
}
public void setSelectionfoot(){
this.setSelection(visibleLastIndex - visibleItemCount + 1);
}
public void onScrollStateChanged(AbsListView arg0, int arg1) {
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (isRefreshable) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (firstItemIndex == 0 && !isRecored) {
isRecored = true;
isPush = true;
startY = (int) event.getY();
}
break;
case MotionEvent.ACTION_UP:
if (state != REFRESHING && state != LOADING) {
if (state == DONE) {
// 什么都不做
}
if (state == PULL_To_REFRESH) {
state = DONE;
changeHeaderViewByState();
Log.v(TAG, "由下拉刷新状态,到done状态");
}
if (state == RELEASE_To_REFRESH) {
state = REFRESHING;
changeHeaderViewByState();
onRefresh();
Log.v(TAG, "由松开刷新状态,到done状态");
}
}
isRecored = false;
isBack = false;
break;
case MotionEvent.ACTION_MOVE:
int tempY = (int) event.getY();
if (!isRecored && firstItemIndex == 0) {
isRecored = true;
startY = tempY;
}
if (state != REFRESHING && isRecored && state != LOADING) {
// 保证在设置padding的过程中,当前的位置一直是在head,否则如果当列表超出屏幕的话,当在上推的时候,列表会同时进行滚动
// 可以松手去刷新了
if (state == RELEASE_To_REFRESH) {
setSelection(0);
// 往上推了,推到了屏幕足够掩盖head的程度,但是还没有推到全部掩盖的地步
if (((tempY - startY) / RATIO < headContentHeight)
&& (tempY - startY) > 0) {
state = PULL_To_REFRESH;
changeHeaderViewByState();
Log.v(TAG, "由松开刷新状态转变到下拉刷新状态");
}
else if (tempY - startY <= 0) {
state = DONE;
changeHeaderViewByState();
Log.v(TAG, "由松开刷新状态转变到done状态");
}
else {
}
}
if (state == PULL_To_REFRESH) {
setSelection(0);
if ((tempY - startY) / RATIO >= headContentHeight) {
state = RELEASE_To_REFRESH;
isBack = true;
changeHeaderViewByState();
}
// 一下子推到顶了
else if (tempY - startY <= 0) {
state = DONE;
changeHeaderViewByState();
isPush = false;
}
}
// done状态下
if (state == DONE) {
if (tempY - startY > 0) {
state = PULL_To_REFRESH;
changeHeaderViewByState();
}
}
// 更新headView的size
if (state == PULL_To_REFRESH) {
headView.setPadding(0, -1 * headContentHeight
+ (tempY - startY) / RATIO, 0, 0);
}
// 更新headView的paddingTop
if (state == RELEASE_To_REFRESH) {
headView.setPadding(0, (tempY - startY) / RATIO
- headContentHeight, 0, 0);
}
}
break;
}
}
return super.onTouchEvent(event);
}
// 当状态改变时候,调用该方法,以更新界面
private void changeHeaderViewByState() {
switch (state) {
case RELEASE_To_REFRESH:
arrowImageView.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);
tipsTextview.setVisibility(View.VISIBLE);
lastUpdatedTextView.setVisibility(View.VISIBLE);
arrowImageView.clearAnimation();
arrowImageView.startAnimation(animation);
tipsTextview.setText(getResources().getString(R.string.release_to_refresh));
break;
case PULL_To_REFRESH:
progressBar.setVisibility(View.GONE);
tipsTextview.setVisibility(View.VISIBLE);
lastUpdatedTextView.setVisibility(View.VISIBLE);
arrowImageView.clearAnimation();
arrowImageView.setVisibility(View.VISIBLE);
// 是由RELEASE_To_REFRESH状态转变来的
if (isBack) {
isBack = false;
arrowImageView.clearAnimation();
arrowImageView.startAnimation(reverseAnimation);
tipsTextview.setText(getResources().getString(R.string.pull_to_refresh));
} else {
tipsTextview.setText(getResources().getString(R.string.pull_to_refresh));
}
break;
case REFRESHING:
headView.setPadding(0, 0, 0, 0);
progressBar.setVisibility(View.VISIBLE);
arrowImageView.clearAnimation();
arrowImageView.setVisibility(View.GONE);
tipsTextview.setText(getResources().getString(R.string.refreshing));
lastUpdatedTextView.setVisibility(View.VISIBLE);
break;
case DONE:
headView.setPadding(0, -1 * headContentHeight, 0, 0);
progressBar.setVisibility(View.GONE);
arrowImageView.clearAnimation();
arrowImageView.setImageResource(R.drawable.pulltorefresh);
tipsTextview.setText(getResources().getString(R.string.pull_to_refresh));
lastUpdatedTextView.setVisibility(View.VISIBLE);
break;
}
}
public void setonRefreshListener(OnRefreshListener refreshListener) {
this.refreshListener = refreshListener;
isRefreshable = true;
}
public interface OnRefreshListener {
public void onRefresh();
}
public void onRefreshComplete() {
state = DONE;
lastUpdatedTextView.setText(getResources().getString(R.string.updating) + new Date().toLocaleString());
changeHeaderViewByState();
invalidateViews();
setSelection(0);
}
private void onRefresh() {
if (refreshListener != null) {
refreshListener.onRefresh();
}
}
public void clickToRefresh(){
state = REFRESHING;
changeHeaderViewByState();
}
private void measureView(View child) {
ViewGroup.LayoutParams p = child.getLayoutParams();
if (p == null) {
p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);
int lpHeight = p.height;
int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,
MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0,
MeasureSpec.UNSPECIFIED);
}
child.measure(childWidthSpec, childHeightSpec);
}
public void setAdapter(BaseAdapter adapter) {
lastUpdatedTextView.setText(getResources().getString(R.string.updating) + new Date().toLocaleString());
super.setAdapter(adapter);
}
}
创建实体为解析网络获取的XML文件做准备: Notice.java
package com.example.SQLite;
/**
* Created with IntelliJ IDEA.
* User: hld
* Date: 14-1-24
* Time: 上午9:50
* To change this template use File | Settings | File Templates.
*/
public class Notice {
private String id;
private String title;
private String wordTitle;
private String wordPath;
private String content;
private String createTime;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getWordTitle() {
return wordTitle;
}
public void setWordTitle(String wordTitle) {
this.wordTitle = wordTitle;
}
public String getWordPath() {
return wordPath;
}
public void setWordPath(String wordPath) {
this.wordPath = wordPath;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
解析网络传回的XML文件:NoticeParseXML.java
package com.example.SQLite;
import android.util.Xml;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* Created with IntelliJ IDEA.
* User: hld
* Date: 14-1-24
* Time: 上午10:02
* To change this template use File | Settings | File Templates.
*/
public class NoticeParseXML {
private List<Notice> list;
private Notice notice;
public NoticeParseXML(InputStream inputStream) throws XmlPullParserException, IOException {
XmlPullParser parser= Xml.newPullParser();
parser.setInput(inputStream,"UTF-8");
int event=parser.getEventType();
while (event!=XmlPullParser.END_DOCUMENT){
switch (event){
case XmlPullParser.START_DOCUMENT:
list=new ArrayList<Notice>();
break;
case XmlPullParser.START_TAG:
//此处按照协议里面字段依次获取XML里面的数据
if ("list".equals(parser.getName())){
notice=new Notice();
}else if ("ID".equals(parser.getName())){
notice.setId(parser.nextText());
}else if ("title".equals(parser.getName())){
notice.setTitle(parser.nextText());
}else if ("wordTitle".equals(parser.getName())){
notice.setWordTitle(parser.nextText());
}else if ("wordPath".equals(parser.getName())){
notice.setWordPath(parser.nextText());
}else if ("content".equals(parser.getName())){
notice.setContent(parser.nextText());
}else if("createTime".equals(parser.getName())){
notice.setCreateTime(parser.nextText());
}
break;
case XmlPullParser.END_TAG:
if ("list".equals(parser.getName())){
list.add(notice);
notice=null;
}
break;
default:
break;
}
event=parser.next();
}
}
public List<Notice> getList() {
return list;
}
}
主界面:NoticeActivity.java
package com.example.SQLite;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.*;
import android.widget.*;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.xmlpull.v1.XmlPullParserException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class NoticeActivity extends Activity {
private TextView mark;
private RTPullListView noticelistview;
private ArrayList<HashMap<String,?>> data=new ArrayList<HashMap<String, ?>>();
private InputStream isInputStream;
private BaseAdapter baseAdapter;
private static final int LOAD_NEW_INFO = 5;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
DBHelper.init(this);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}//To change body of overridden methods use File | Settings | File Templates.
setContentView(R.layout.notice_activity);
//查询SQLite数据
queryAll();
//首次登陆,SQLite无数据,需要这个方法
FirstLogin();
noticelistview=(RTPullListView)findViewById(R.id.noticelistview);
//下拉刷新
noticelistview.setonRefreshListener(new RTPullListView.OnRefreshListener() {
@Override
public void onRefresh() {
PullToRefresh();
}
});
baseAdapter=new BaseAdapter() {
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return data.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView==null){
LayoutInflater layoutInflater=getLayoutInflater();
convertView=layoutInflater.inflate(R.layout.main_list_item,parent,false);
}
//将HashMap里面的数据展示到页面
Map<String,Object> itemData=(Map<String,Object>)getItem(position);
TextView titleTextView=(TextView)convertView.findViewById(R.id.titleTextView);
TextView dataTextView=(TextView)convertView.findViewById(R.id.dataTextView);
mark=(TextView)convertView.findViewById(R.id.mark);
mark.setText(itemData.get("status").toString());
if (itemData.get("status").toString().equals("已读")){
mark.setTextColor(Color.GREEN);
}else{
mark.setTextColor(Color.RED);
}
String Title=itemData.get("Title").toString();
titleTextView.setText(Title);
dataTextView.setText(itemData.get("createTime").toString());
return convertView;
}
};
noticelistview.setAdapter(baseAdapter);
noticelistview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long itemId) {
HashMap<String,Object> Mp= (HashMap<String, Object>) data.get(position-1);
System.out.println("<<<<<<<"+Mp.toString());
String ID=Mp.get("id").toString();
if (Mp.containsKey("status")){
Mp.remove("status");
Mp.put("status","已读");
data.remove(position-1);
data.add(position-1,Mp);
baseAdapter.notifyDataSetChanged();
}
//根据ID从数据库中查出需要传递的数据
SQLiteDatabase db= DBHelper.getDB();
Cursor cursor=db.query("notice_info",null,"id=?",new String[]{ID},null,null,null);
System.out.println("<<<<<<"+position);
String WordTitle="";
String WordPath="";
String Title="";
String Content="";
while (cursor.moveToNext()){
WordTitle=cursor.getString(cursor.getColumnIndex("wordTitle"));
WordPath=cursor.getString(cursor.getColumnIndex("wordPath"));
Title=cursor.getString(cursor.getColumnIndex("title"));
Content=cursor.getString(cursor.getColumnIndex("content"));
//将查出来的这条数据的状态改为已读,然后插入数据库
ContentValues contentValues = new ContentValues();
contentValues.put("status","已读");
long dd=db.update("notice_info",contentValues, "id=?", new String[]{String.valueOf(ID)});
System.out.println("<<<<<<<"+dd+"<<<<"+ID);
}
//将公告详情所需的数据传递过去
Intent intent=new Intent(NoticeActivity.this,MyActivity.class);
String[] aa=WordTitle.split("\\|");
String wordTitle=aa[0];
intent.putExtra("Title",Title);
intent.putExtra("WordTitle",wordTitle);
intent.putExtra("WordPath",WordPath);
intent.putExtra("Content",Content);
startActivity(intent);
}
});
}
//控制下拉刷新的Handler
private Handler myHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case LOAD_NEW_INFO:
queryAll();
baseAdapter.notifyDataSetChanged();
noticelistview.onRefreshComplete();
break;
case 100:
Toast toast=Toast.makeText(NoticeActivity.this,"请检查网络连接是否正确",500);
toast.setGravity(Gravity.CENTER,0,0);
toast.show();
break;
case 200:
showDataErrorMessage();
break;
case 300:
showServerErrorMessage();
break;
default:
break;
}
}
};
private void PullToRefresh(){
new Thread(new Runnable() {
@Override
public void run() {
try {
SQLiteDatabase db= DBHelper.getDB();
//获取网络请求返回的字符串
String resultStr = requestServerDara();
System.out.println("<<<<<<<<"+resultStr);
//读取返回的字符串
try {
isInputStream=new ByteArrayInputStream(resultStr.getBytes());
}catch (Exception e){
myHandler.sendEmptyMessage(100);
e.printStackTrace();
}
//解析读取到的字符串
NoticeParseXML noticeParseXML = new NoticeParseXML(isInputStream);
List<Notice> list=noticeParseXML.getList();
// Cursor cursor1=db.rawQuery("select * from notice_info",null);
Cursor cursor1=db.query("notice_info", null, null, null, null, null,"id DESC");
int Id = 0;
if(cursor1.moveToPosition(0)==true){
Id= Integer.parseInt(cursor1.getString(cursor1.getColumnIndex("id")));
System.out.println("<<<<<<<<<"+Id+"<<<<<<<<<<<<<<<<<<");
}
//将解析到的内容添加到SQLite里面
for(int i=0;i<list.size();i++){
Notice notice=list.get(i);
int id= Integer.parseInt(notice.getId());
String title=notice.getTitle();
String wordTitle=notice.getWordTitle();
String wordPath=notice.getWordPath();
String content=notice.getContent();
String createTime=notice.getCreateTime();
//这里在往数据库插入的时候做了判断,如果当前这条数据的ID小于数据库中最大的ID则他不是最新数 据,不需要往数据库里保存
if (id>Id){
System.out.println("<<<<<<<<<"+id+"LLLLLLLLLLLLLL");
ContentValues contentValues=new ContentValues();
contentValues.put("id",id);
contentValues.put("status","未读");
contentValues.put("title",title);
contentValues.put("wordTitle",wordTitle);
contentValues.put("wordPath",wordPath);
contentValues.put("content",content);
contentValues.put("createTime", createTime);
db.insert("notice_info", null, contentValues);
}
}
myHandler.sendEmptyMessage(LOAD_NEW_INFO);
}catch (XmlPullParserException e) {
myHandler.sendEmptyMessage(200);
} catch (IOException e) {
myHandler.sendEmptyMessage(300);
}
}
}).start();
}
//请求并解析网络返回XML文件并存进SQLite里面然后读取
private void mainMethod(){
final ProgressDialog progressDialog=new ProgressDialog(this);
progressDialog.setMessage("正在加载……");
AsyncTask<Integer,Integer,Integer> asyncTask=new AsyncTask<Integer, Integer, Integer>() {
@Override
protected Integer doInBackground(Integer... params) {
try {
String resultStr= null;
NoticeParseXML noticeParseXML= null;
//获取网络返回的XML文件
resultStr = requestServerDara();
//读取XML文件
isInputStream=new ByteArrayInputStream(resultStr.getBytes());
//解析XMl文件
noticeParseXML = new NoticeParseXML(isInputStream);
List<Notice> list=noticeParseXML.getList();
//保存到SQLite里面
SQLiteDatabase db= DBHelper.getDB();
deleteAll();
for(int i=0;i<list.size();i++){
Notice notice=list.get(i);
String status="未读";
int id= Integer.parseInt(notice.getId());
String title=notice.getTitle();
String wordTitle=notice.getWordTitle();
String wordPath=notice.getWordPath();
String content=notice.getContent();
String createTime=notice.getCreateTime();
ContentValues contentValues=new ContentValues();
contentValues.put("id",id);
contentValues.put("status",status);
contentValues.put("title",title);
contentValues.put("wordTitle",wordTitle);
contentValues.put("wordPath",wordPath);
contentValues.put("content",content);
contentValues.put("createTime",createTime);
db.insert("notice_info", null, contentValues);
}
queryAll();
myHandler.sendEmptyMessage(LOAD_NEW_INFO);
}catch (XmlPullParserException e) {
myHandler.sendEmptyMessage(200);
} catch (IOException e) {
myHandler.sendEmptyMessage(300);
showServerErrorMessage();
}
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
protected void onPreExecute() {
progressDialog.show();
super.onPreExecute(); //To change body of overridden methods use File | Settings | File Templates.
}
@Override
protected void onPostExecute(Integer integer) {
progressDialog.dismiss();
LinearLayout textView_isnull = (LinearLayout) findViewById(R.id.doc_isnull);
if (data.size()>0) {
textView_isnull.setVisibility(View.GONE);
Log.d("", "=======Gone");
} else {
textView_isnull.setVisibility(View.VISIBLE);
Log.d("", "=======visible");
}
super.onPostExecute(integer); //To change body of overridden methods use File | Settings | File Templates.
}
};
asyncTask.execute(0);
}
//请求网络获取返回的XML文件
private String requestServerDara(){
//请求地址
String url="http://192.168.168.5:8080/OAWeb.aspx?PacketType=0002";
HttpGet httpGet=new HttpGet(url);
DefaultHttpClient httpClient=new DefaultHttpClient();
HttpResponse response= null;
try {
response = httpClient.execute(httpGet);
String resultStr= EntityUtils.toString(response.getEntity(),"UTF-8");
return resultStr;
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
return null;
}
private void showServerErrorMessage(){
Toast toast=Toast.makeText(this,"请检查网络连接是否正确",Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER,0,0);
toast.show();
}
private void showDataErrorMessage(){
Toast toast=Toast.makeText(this,"数据格式异常",Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER,0,0);
toast.show();
}
private void deleteAll(){
SQLiteDatabase db = DBHelper.getDB();
db.delete("notice_info",null,null);
}
private void queryAll(){
//读取SQLite里面的数据
SQLiteDatabase db= DBHelper.getDB();
//这里是把SQLite里面的数据进行排序,依据ID由大到小排序,这样可以保证咱们ListView展示在最上面的一条 数据是最新的一条
Cursor cursor=db.query("notice_info", null, null, null, null, null,"id DESC");
String Id=null;
String Status=null;
String Title=null;
String WordTitle=null;
String WordPath=null;
String Content=null;
String CreateTime=null;
if(data.size()>0){
data.clear();
}
while (cursor.moveToNext()){
//将数据放到HashMap里面
HashMap<String,Object> item=new HashMap<String, Object>();
Id=cursor.getString(cursor.getColumnIndex("id"));
Status=cursor.getString(cursor.getColumnIndex("status"));
Title=cursor.getString(cursor.getColumnIndex("title"));
WordTitle=cursor.getString(cursor.getColumnIndex("wordTitle"));
WordPath=cursor.getString(cursor.getColumnIndex("wordPath"));
Content=cursor.getString(cursor.getColumnIndex("content"));
CreateTime=cursor.getString(cursor.getColumnIndex("createTime"));
item.put("id",Id);
item.put("status",Status);
item.put("Title",Title);
item.put("createTime",CreateTime);
item.put("wordTitle",WordTitle);
item.put("wordPath",WordPath);
item.put("content", Content);
data.add(item);
System.out.println("<<<<<<<<<"+data.toString());
}
}
//第一次登陆SQLite无数据需要此方法
private void FirstLogin(){
LinearLayout textView_isnull = (LinearLayout) findViewById(R.id.doc_isnull);
if (data.size()>0) {
textView_isnull.setVisibility(View.GONE);
Log.d("", "=======Gone");
} else {
textView_isnull.setVisibility(View.VISIBLE);
Log.d("", "=======visible");
}
textView_isnull.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mainMethod();
if(baseAdapter!=null){
baseAdapter.notifyDataSetChanged();
}
}
});
}
}
点击ListView之后哦进去页面:
源码下载地址
下拉刷新头文件的布局:pulllist-head.xml
首次登录进来SQLite里面没有数据,需手动点击请求网络加载:
之后就可以下拉刷新了:
<?xml version="1.0" encoding="utf-8"?>
<!-- ListView的头部 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:background="#FFFFFFFF" >
<!-- 内容 -->
<RelativeLayout
android:id="@+id/head_contentLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:paddingLeft="10dp" >
<!-- 箭头图像、进度条 -->
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true" >
<!-- 箭头 -->
<ImageView
android:id="@+id/head_arrowImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/pulltorefresh" />
<!-- 进度条 -->
<ProgressBar
android:id="@+id/head_progressBar"
style="@android:style/Widget.ProgressBar.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
</FrameLayout>
<!-- 提示、最近更新 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:gravity="center_horizontal"
android:orientation="vertical" >
<!-- 提示 -->
<TextView
android:id="@+id/head_tipsTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp" />
<!-- 最近更新 -->
<TextView
android:id="@+id/head_lastUpdatedTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="13sp" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
主页面布局文件:notice-activity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff">
<LinearLayout android:id="@+id/doc_isnull"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/empty_view"
>
</ImageView>
</LinearLayout>
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content">
//listview 注意前面路径一定要写对 否则会报错,小五就犯过这个低级错误
<com.example.SQLite.RTPullListView android:id="@+id/noticelistview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginRight="3dp"
android:layout_marginLeft="3dp"
android:focusable="true"
android:divider="@null"
android:cacheColorHint="#00000000"/>
</LinearLayout>
</LinearLayout>
listview里面的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:focusableInTouchMode="false"
android:layout_height="60dp">
<ImageView
android:layout_width="fill_parent"
android:layout_height="1dp"
android:background="#cccccc">
</ImageView>
<LinearLayout android:layout_width="fill_parent"
android:layout_height="59dp"
android:focusableInTouchMode="false"
android:background="#ffffff"
android:orientation="vertical">
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:focusable="false"
android:layout_marginTop="5dp"
android:orientation="horizontal">
<LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:focusable="false"
android:layout_marginLeft="10dp"
android:background="@drawable/notice_status">
<TextView android:id="@+id/mark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:layout_marginLeft="10dp"
android:gravity="left"
android:focusable="false"
android:layout_marginRight="10dp"
android:textColor="#B71C00"
android:text=""/>
</LinearLayout>
<TextView android:id="@+id/titleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginLeft="10dp"
android:focusable="false"
android:layout_weight="1"
android:textColor="@color/black"
android:textSize="15dp"
android:singleLine="true"
android:text=""/>
<ImageView android:id="@+id/mark"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginRight="10dp"
android:layout_marginTop="5dp"
android:focusable="false"
android:layout_gravity="center_vertical"
android:background="@drawable/arrows"/>
</LinearLayout>
<LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false">
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="70dp"
android:focusable="false"
android:layout_marginTop="3dp"
android:background="@drawable/timeicon"/>
<TextView android:id="@+id/dataTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:focusable="false"
android:textColor="@color/TimeColor"
android:text=""/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
listview点击进去布局文件:myactivity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg4">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我进来了"
android:layout_gravity="center"
android:layout_marginTop="100dp"
android:textColor="@color/black"
android:textSize="40dp"/>
</LinearLayout>
java代码DBHelper.java
这个类是用来在SQLite中创建表
package com.example.SQLite;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.AssetManager;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DBHelper extends SQLiteOpenHelper {
private static DBHelper dbHelper;
private static int version = 1;
private Context context;
private SQLiteDatabase db;
public DBHelper(Context context) {
super(context, "sqlitedemo", null, version);
this.context = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
this.db = db;
try {
initDB();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
public static synchronized void init(Context context) throws NameNotFoundException {
if (dbHelper == null) {
dbHelper = new DBHelper(context);
}
}
public static SQLiteDatabase getDB() {
return dbHelper.getWritableDatabase();
}
private void initDB() throws IOException {
AssetManager assetManager = context.getAssets();
InputStream inStream = assetManager.open("notice_sql.sql");
BufferedReader reader = new BufferedReader(new InputStreamReader(
inStream));
StringBuffer sql = new StringBuffer();
String line = null;
while ((line = reader.readLine()) != null) {
sql.append(line);
}
reader.close();
Log.d("SQLite", "Init db " + sql.toString());
db.execSQL(sql.toString());
Log.i("SQLite", "Init database");
}
public SQLiteDatabase getDb() {
return db;
}
}
下拉刷新的类:RTPullListView.java
package com.example.SQLite;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.*;
import android.widget.AbsListView.OnScrollListener;
import java.util.Date;
public class RTPullListView extends ListView implements OnScrollListener {
private static final String TAG = "RTPullListView";
private final static int RELEASE_To_REFRESH = 0;
private final static int PULL_To_REFRESH = 1;
private final static int REFRESHING = 2;
private final static int DONE = 3;
private final static int LOADING = 4;
// 实际的padding的距离与界面上偏移距离的比例
private final static int RATIO = 3;
private LayoutInflater inflater;
private LinearLayout headView;
private TextView tipsTextview;
private TextView lastUpdatedTextView;
private ImageView arrowImageView;
private ProgressBar progressBar;
private RotateAnimation animation;
private RotateAnimation reverseAnimation;
// 用于保证startY的值在一个完整的touch事件中只被记录一次
private boolean isRecored;
private int headContentHeight;
private int startY;
private int firstItemIndex;
private int state;
private boolean isBack;
private OnRefreshListener refreshListener;
private boolean isRefreshable;
private boolean isPush;
private int visibleLastIndex;
private int visibleItemCount;
public RTPullListView(Context context) {
super(context);
init(context);
}
public RTPullListView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
inflater = LayoutInflater.from(context);
headView = (LinearLayout) inflater.inflate(R.layout.pulllist_head, null);
arrowImageView = (ImageView) headView.findViewById(R.id.head_arrowImageView);
//arrowImageView.setMinimumWidth(70);
//arrowImageView.setMinimumHeight(50);
progressBar = (ProgressBar) headView.findViewById(R.id.head_progressBar);
tipsTextview = (TextView) headView.findViewById(R.id.head_tipsTextView);
lastUpdatedTextView = (TextView) headView.findViewById(R.id.head_lastUpdatedTextView);
measureView(headView);
headContentHeight = headView.getMeasuredHeight();
//headContentWidth = headView.getMeasuredWidth();
headView.setPadding(0, -1 * headContentHeight, 0, 0);
headView.invalidate();
addHeaderView(headView, null, false);
setOnScrollListener(this);
animation = new RotateAnimation(0, -180,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
animation.setInterpolator(new LinearInterpolator());
animation.setDuration(250);
animation.setFillAfter(true);
reverseAnimation = new RotateAnimation(-180, 0,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
reverseAnimation.setInterpolator(new LinearInterpolator());
reverseAnimation.setDuration(200);
reverseAnimation.setFillAfter(true);
state = DONE;
isRefreshable = false;
isPush = true;
}
public void onScroll(AbsListView arg0, int firstVisiableItem, int arg2,
int arg3) {
firstItemIndex = firstVisiableItem;
visibleLastIndex = firstVisiableItem + arg2 - 1;
visibleItemCount = arg2;
if(firstItemIndex == 1 && !isPush){
setSelection(0);
}
}
public void setSelectionfoot(){
this.setSelection(visibleLastIndex - visibleItemCount + 1);
}
public void onScrollStateChanged(AbsListView arg0, int arg1) {
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (isRefreshable) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (firstItemIndex == 0 && !isRecored) {
isRecored = true;
isPush = true;
startY = (int) event.getY();
}
break;
case MotionEvent.ACTION_UP:
if (state != REFRESHING && state != LOADING) {
if (state == DONE) {
// 什么都不做
}
if (state == PULL_To_REFRESH) {
state = DONE;
changeHeaderViewByState();
Log.v(TAG, "由下拉刷新状态,到done状态");
}
if (state == RELEASE_To_REFRESH) {
state = REFRESHING;
changeHeaderViewByState();
onRefresh();
Log.v(TAG, "由松开刷新状态,到done状态");
}
}
isRecored = false;
isBack = false;
break;
case MotionEvent.ACTION_MOVE:
int tempY = (int) event.getY();
if (!isRecored && firstItemIndex == 0) {
isRecored = true;
startY = tempY;
}
if (state != REFRESHING && isRecored && state != LOADING) {
// 保证在设置padding的过程中,当前的位置一直是在head,否则如果当列表超出屏幕的话,当在上推的时候,列表会同时进行滚动
// 可以松手去刷新了
if (state == RELEASE_To_REFRESH) {
setSelection(0);
// 往上推了,推到了屏幕足够掩盖head的程度,但是还没有推到全部掩盖的地步
if (((tempY - startY) / RATIO < headContentHeight)
&& (tempY - startY) > 0) {
state = PULL_To_REFRESH;
changeHeaderViewByState();
Log.v(TAG, "由松开刷新状态转变到下拉刷新状态");
}
else if (tempY - startY <= 0) {
state = DONE;
changeHeaderViewByState();
Log.v(TAG, "由松开刷新状态转变到done状态");
}
else {
}
}
if (state == PULL_To_REFRESH) {
setSelection(0);
if ((tempY - startY) / RATIO >= headContentHeight) {
state = RELEASE_To_REFRESH;
isBack = true;
changeHeaderViewByState();
}
// 一下子推到顶了
else if (tempY - startY <= 0) {
state = DONE;
changeHeaderViewByState();
isPush = false;
}
}
// done状态下
if (state == DONE) {
if (tempY - startY > 0) {
state = PULL_To_REFRESH;
changeHeaderViewByState();
}
}
// 更新headView的size
if (state == PULL_To_REFRESH) {
headView.setPadding(0, -1 * headContentHeight
+ (tempY - startY) / RATIO, 0, 0);
}
// 更新headView的paddingTop
if (state == RELEASE_To_REFRESH) {
headView.setPadding(0, (tempY - startY) / RATIO
- headContentHeight, 0, 0);
}
}
break;
}
}
return super.onTouchEvent(event);
}
// 当状态改变时候,调用该方法,以更新界面
private void changeHeaderViewByState() {
switch (state) {
case RELEASE_To_REFRESH:
arrowImageView.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);
tipsTextview.setVisibility(View.VISIBLE);
lastUpdatedTextView.setVisibility(View.VISIBLE);
arrowImageView.clearAnimation();
arrowImageView.startAnimation(animation);
tipsTextview.setText(getResources().getString(R.string.release_to_refresh));
break;
case PULL_To_REFRESH:
progressBar.setVisibility(View.GONE);
tipsTextview.setVisibility(View.VISIBLE);
lastUpdatedTextView.setVisibility(View.VISIBLE);
arrowImageView.clearAnimation();
arrowImageView.setVisibility(View.VISIBLE);
// 是由RELEASE_To_REFRESH状态转变来的
if (isBack) {
isBack = false;
arrowImageView.clearAnimation();
arrowImageView.startAnimation(reverseAnimation);
tipsTextview.setText(getResources().getString(R.string.pull_to_refresh));
} else {
tipsTextview.setText(getResources().getString(R.string.pull_to_refresh));
}
break;
case REFRESHING:
headView.setPadding(0, 0, 0, 0);
progressBar.setVisibility(View.VISIBLE);
arrowImageView.clearAnimation();
arrowImageView.setVisibility(View.GONE);
tipsTextview.setText(getResources().getString(R.string.refreshing));
lastUpdatedTextView.setVisibility(View.VISIBLE);
break;
case DONE:
headView.setPadding(0, -1 * headContentHeight, 0, 0);
progressBar.setVisibility(View.GONE);
arrowImageView.clearAnimation();
arrowImageView.setImageResource(R.drawable.pulltorefresh);
tipsTextview.setText(getResources().getString(R.string.pull_to_refresh));
lastUpdatedTextView.setVisibility(View.VISIBLE);
break;
}
}
public void setonRefreshListener(OnRefreshListener refreshListener) {
this.refreshListener = refreshListener;
isRefreshable = true;
}
public interface OnRefreshListener {
public void onRefresh();
}
public void onRefreshComplete() {
state = DONE;
lastUpdatedTextView.setText(getResources().getString(R.string.updating) + new Date().toLocaleString());
changeHeaderViewByState();
invalidateViews();
setSelection(0);
}
private void onRefresh() {
if (refreshListener != null) {
refreshListener.onRefresh();
}
}
public void clickToRefresh(){
state = REFRESHING;
changeHeaderViewByState();
}
private void measureView(View child) {
ViewGroup.LayoutParams p = child.getLayoutParams();
if (p == null) {
p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);
int lpHeight = p.height;
int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,
MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0,
MeasureSpec.UNSPECIFIED);
}
child.measure(childWidthSpec, childHeightSpec);
}
public void setAdapter(BaseAdapter adapter) {
lastUpdatedTextView.setText(getResources().getString(R.string.updating) + new Date().toLocaleString());
super.setAdapter(adapter);
}
}
创建实体为解析网络获取的XML文件做准备: Notice.java
package com.example.SQLite;
/**
* Created with IntelliJ IDEA.
* User: hld
* Date: 14-1-24
* Time: 上午9:50
* To change this template use File | Settings | File Templates.
*/
public class Notice {
private String id;
private String title;
private String wordTitle;
private String wordPath;
private String content;
private String createTime;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getWordTitle() {
return wordTitle;
}
public void setWordTitle(String wordTitle) {
this.wordTitle = wordTitle;
}
public String getWordPath() {
return wordPath;
}
public void setWordPath(String wordPath) {
this.wordPath = wordPath;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
解析网络传回的XML文件:NoticeParseXML.java
package com.example.SQLite;
import android.util.Xml;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* Created with IntelliJ IDEA.
* User: hld
* Date: 14-1-24
* Time: 上午10:02
* To change this template use File | Settings | File Templates.
*/
public class NoticeParseXML {
private List<Notice> list;
private Notice notice;
public NoticeParseXML(InputStream inputStream) throws XmlPullParserException, IOException {
XmlPullParser parser= Xml.newPullParser();
parser.setInput(inputStream,"UTF-8");
int event=parser.getEventType();
while (event!=XmlPullParser.END_DOCUMENT){
switch (event){
case XmlPullParser.START_DOCUMENT:
list=new ArrayList<Notice>();
break;
case XmlPullParser.START_TAG:
//此处按照协议里面字段依次获取XML里面的数据
if ("list".equals(parser.getName())){
notice=new Notice();
}else if ("ID".equals(parser.getName())){
notice.setId(parser.nextText());
}else if ("title".equals(parser.getName())){
notice.setTitle(parser.nextText());
}else if ("wordTitle".equals(parser.getName())){
notice.setWordTitle(parser.nextText());
}else if ("wordPath".equals(parser.getName())){
notice.setWordPath(parser.nextText());
}else if ("content".equals(parser.getName())){
notice.setContent(parser.nextText());
}else if("createTime".equals(parser.getName())){
notice.setCreateTime(parser.nextText());
}
break;
case XmlPullParser.END_TAG:
if ("list".equals(parser.getName())){
list.add(notice);
notice=null;
}
break;
default:
break;
}
event=parser.next();
}
}
public List<Notice> getList() {
return list;
}
}
主界面:NoticeActivity.java
package com.example.SQLite;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.*;
import android.widget.*;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.xmlpull.v1.XmlPullParserException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class NoticeActivity extends Activity {
private TextView mark;
private RTPullListView noticelistview;
private ArrayList<HashMap<String,?>> data=new ArrayList<HashMap<String, ?>>();
private InputStream isInputStream;
private BaseAdapter baseAdapter;
private static final int LOAD_NEW_INFO = 5;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
DBHelper.init(this);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}//To change body of overridden methods use File | Settings | File Templates.
setContentView(R.layout.notice_activity);
//查询SQLite数据
queryAll();
//首次登陆,SQLite无数据,需要这个方法
FirstLogin();
noticelistview=(RTPullListView)findViewById(R.id.noticelistview);
//下拉刷新
noticelistview.setonRefreshListener(new RTPullListView.OnRefreshListener() {
@Override
public void onRefresh() {
PullToRefresh();
}
});
baseAdapter=new BaseAdapter() {
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return data.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView==null){
LayoutInflater layoutInflater=getLayoutInflater();
convertView=layoutInflater.inflate(R.layout.main_list_item,parent,false);
}
//将HashMap里面的数据展示到页面
Map<String,Object> itemData=(Map<String,Object>)getItem(position);
TextView titleTextView=(TextView)convertView.findViewById(R.id.titleTextView);
TextView dataTextView=(TextView)convertView.findViewById(R.id.dataTextView);
mark=(TextView)convertView.findViewById(R.id.mark);
mark.setText(itemData.get("status").toString());
if (itemData.get("status").toString().equals("已读")){
mark.setTextColor(Color.GREEN);
}else{
mark.setTextColor(Color.RED);
}
String Title=itemData.get("Title").toString();
titleTextView.setText(Title);
dataTextView.setText(itemData.get("createTime").toString());
return convertView;
}
};
noticelistview.setAdapter(baseAdapter);
noticelistview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long itemId) {
HashMap<String,Object> Mp= (HashMap<String, Object>) data.get(position-1);
System.out.println("<<<<<<<"+Mp.toString());
String ID=Mp.get("id").toString();
if (Mp.containsKey("status")){
Mp.remove("status");
Mp.put("status","已读");
data.remove(position-1);
data.add(position-1,Mp);
baseAdapter.notifyDataSetChanged();
}
//根据ID从数据库中查出需要传递的数据
SQLiteDatabase db= DBHelper.getDB();
Cursor cursor=db.query("notice_info",null,"id=?",new String[]{ID},null,null,null);
System.out.println("<<<<<<"+position);
String WordTitle="";
String WordPath="";
String Title="";
String Content="";
while (cursor.moveToNext()){
WordTitle=cursor.getString(cursor.getColumnIndex("wordTitle"));
WordPath=cursor.getString(cursor.getColumnIndex("wordPath"));
Title=cursor.getString(cursor.getColumnIndex("title"));
Content=cursor.getString(cursor.getColumnIndex("content"));
//将查出来的这条数据的状态改为已读,然后插入数据库
ContentValues contentValues = new ContentValues();
contentValues.put("status","已读");
long dd=db.update("notice_info",contentValues, "id=?", new String[]{String.valueOf(ID)});
System.out.println("<<<<<<<"+dd+"<<<<"+ID);
}
//将公告详情所需的数据传递过去
Intent intent=new Intent(NoticeActivity.this,MyActivity.class);
String[] aa=WordTitle.split("\\|");
String wordTitle=aa[0];
intent.putExtra("Title",Title);
intent.putExtra("WordTitle",wordTitle);
intent.putExtra("WordPath",WordPath);
intent.putExtra("Content",Content);
startActivity(intent);
}
});
}
//控制下拉刷新的Handler
private Handler myHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case LOAD_NEW_INFO:
queryAll();
baseAdapter.notifyDataSetChanged();
noticelistview.onRefreshComplete();
break;
case 100:
Toast toast=Toast.makeText(NoticeActivity.this,"请检查网络连接是否正确",500);
toast.setGravity(Gravity.CENTER,0,0);
toast.show();
break;
case 200:
showDataErrorMessage();
break;
case 300:
showServerErrorMessage();
break;
default:
break;
}
}
};
private void PullToRefresh(){
new Thread(new Runnable() {
@Override
public void run() {
try {
SQLiteDatabase db= DBHelper.getDB();
//获取网络请求返回的字符串
String resultStr = requestServerDara();
System.out.println("<<<<<<<<"+resultStr);
//读取返回的字符串
try {
isInputStream=new ByteArrayInputStream(resultStr.getBytes());
}catch (Exception e){
myHandler.sendEmptyMessage(100);
e.printStackTrace();
}
//解析读取到的字符串
NoticeParseXML noticeParseXML = new NoticeParseXML(isInputStream);
List<Notice> list=noticeParseXML.getList();
// Cursor cursor1=db.rawQuery("select * from notice_info",null);
Cursor cursor1=db.query("notice_info", null, null, null, null, null,"id DESC");
int Id = 0;
if(cursor1.moveToPosition(0)==true){
Id= Integer.parseInt(cursor1.getString(cursor1.getColumnIndex("id")));
System.out.println("<<<<<<<<<"+Id+"<<<<<<<<<<<<<<<<<<");
}
//将解析到的内容添加到SQLite里面
for(int i=0;i<list.size();i++){
Notice notice=list.get(i);
int id= Integer.parseInt(notice.getId());
String title=notice.getTitle();
String wordTitle=notice.getWordTitle();
String wordPath=notice.getWordPath();
String content=notice.getContent();
String createTime=notice.getCreateTime();
//这里在往数据库插入的时候做了判断,如果当前这条数据的ID小于数据库中最大的ID则他不是最新数 据,不需要往数据库里保存
if (id>Id){
System.out.println("<<<<<<<<<"+id+"LLLLLLLLLLLLLL");
ContentValues contentValues=new ContentValues();
contentValues.put("id",id);
contentValues.put("status","未读");
contentValues.put("title",title);
contentValues.put("wordTitle",wordTitle);
contentValues.put("wordPath",wordPath);
contentValues.put("content",content);
contentValues.put("createTime", createTime);
db.insert("notice_info", null, contentValues);
}
}
myHandler.sendEmptyMessage(LOAD_NEW_INFO);
}catch (XmlPullParserException e) {
myHandler.sendEmptyMessage(200);
} catch (IOException e) {
myHandler.sendEmptyMessage(300);
}
}
}).start();
}
//请求并解析网络返回XML文件并存进SQLite里面然后读取
private void mainMethod(){
final ProgressDialog progressDialog=new ProgressDialog(this);
progressDialog.setMessage("正在加载……");
AsyncTask<Integer,Integer,Integer> asyncTask=new AsyncTask<Integer, Integer, Integer>() {
@Override
protected Integer doInBackground(Integer... params) {
try {
String resultStr= null;
NoticeParseXML noticeParseXML= null;
//获取网络返回的XML文件
resultStr = requestServerDara();
//读取XML文件
isInputStream=new ByteArrayInputStream(resultStr.getBytes());
//解析XMl文件
noticeParseXML = new NoticeParseXML(isInputStream);
List<Notice> list=noticeParseXML.getList();
//保存到SQLite里面
SQLiteDatabase db= DBHelper.getDB();
deleteAll();
for(int i=0;i<list.size();i++){
Notice notice=list.get(i);
String status="未读";
int id= Integer.parseInt(notice.getId());
String title=notice.getTitle();
String wordTitle=notice.getWordTitle();
String wordPath=notice.getWordPath();
String content=notice.getContent();
String createTime=notice.getCreateTime();
ContentValues contentValues=new ContentValues();
contentValues.put("id",id);
contentValues.put("status",status);
contentValues.put("title",title);
contentValues.put("wordTitle",wordTitle);
contentValues.put("wordPath",wordPath);
contentValues.put("content",content);
contentValues.put("createTime",createTime);
db.insert("notice_info", null, contentValues);
}
queryAll();
myHandler.sendEmptyMessage(LOAD_NEW_INFO);
}catch (XmlPullParserException e) {
myHandler.sendEmptyMessage(200);
} catch (IOException e) {
myHandler.sendEmptyMessage(300);
showServerErrorMessage();
}
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
protected void onPreExecute() {
progressDialog.show();
super.onPreExecute(); //To change body of overridden methods use File | Settings | File Templates.
}
@Override
protected void onPostExecute(Integer integer) {
progressDialog.dismiss();
LinearLayout textView_isnull = (LinearLayout) findViewById(R.id.doc_isnull);
if (data.size()>0) {
textView_isnull.setVisibility(View.GONE);
Log.d("", "=======Gone");
} else {
textView_isnull.setVisibility(View.VISIBLE);
Log.d("", "=======visible");
}
super.onPostExecute(integer); //To change body of overridden methods use File | Settings | File Templates.
}
};
asyncTask.execute(0);
}
//请求网络获取返回的XML文件
private String requestServerDara(){
//请求地址
String url="http://192.168.168.5:8080/OAWeb.aspx?PacketType=0002";
HttpGet httpGet=new HttpGet(url);
DefaultHttpClient httpClient=new DefaultHttpClient();
HttpResponse response= null;
try {
response = httpClient.execute(httpGet);
String resultStr= EntityUtils.toString(response.getEntity(),"UTF-8");
return resultStr;
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
return null;
}
private void showServerErrorMessage(){
Toast toast=Toast.makeText(this,"请检查网络连接是否正确",Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER,0,0);
toast.show();
}
private void showDataErrorMessage(){
Toast toast=Toast.makeText(this,"数据格式异常",Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER,0,0);
toast.show();
}
private void deleteAll(){
SQLiteDatabase db = DBHelper.getDB();
db.delete("notice_info",null,null);
}
private void queryAll(){
//读取SQLite里面的数据
SQLiteDatabase db= DBHelper.getDB();
//这里是把SQLite里面的数据进行排序,依据ID由大到小排序,这样可以保证咱们ListView展示在最上面的一条 数据是最新的一条
Cursor cursor=db.query("notice_info", null, null, null, null, null,"id DESC");
String Id=null;
String Status=null;
String Title=null;
String WordTitle=null;
String WordPath=null;
String Content=null;
String CreateTime=null;
if(data.size()>0){
data.clear();
}
while (cursor.moveToNext()){
//将数据放到HashMap里面
HashMap<String,Object> item=new HashMap<String, Object>();
Id=cursor.getString(cursor.getColumnIndex("id"));
Status=cursor.getString(cursor.getColumnIndex("status"));
Title=cursor.getString(cursor.getColumnIndex("title"));
WordTitle=cursor.getString(cursor.getColumnIndex("wordTitle"));
WordPath=cursor.getString(cursor.getColumnIndex("wordPath"));
Content=cursor.getString(cursor.getColumnIndex("content"));
CreateTime=cursor.getString(cursor.getColumnIndex("createTime"));
item.put("id",Id);
item.put("status",Status);
item.put("Title",Title);
item.put("createTime",CreateTime);
item.put("wordTitle",WordTitle);
item.put("wordPath",WordPath);
item.put("content", Content);
data.add(item);
System.out.println("<<<<<<<<<"+data.toString());
}
}
//第一次登陆SQLite无数据需要此方法
private void FirstLogin(){
LinearLayout textView_isnull = (LinearLayout) findViewById(R.id.doc_isnull);
if (data.size()>0) {
textView_isnull.setVisibility(View.GONE);
Log.d("", "=======Gone");
} else {
textView_isnull.setVisibility(View.VISIBLE);
Log.d("", "=======visible");
}
textView_isnull.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mainMethod();
if(baseAdapter!=null){
baseAdapter.notifyDataSetChanged();
}
}
});
}
}
点击ListView之后哦进去页面:
源码下载地址
相关文章推荐
- oracle中去重复记录 不用distinct
- oracle中去重复记录 不用distinct
- Oracle 11g RAC 下错误集锦之---网卡配置故障
- Zabbix-2.2.2监控MySQL的复制
- Mysql问题
- oracle忘记初始密码的解决方案
- SecureCRT中解决SQLPLUS上下左右键问题
- oracle 10g 和 11g 关于角色口令的区别
- SQL Server中关于标识列的使用说明
- SQL对Xml字段的操作
- SQL对Xml字段的操作
- 菜鸟成长记
- 调整oracle回滚的速度
- oracle中的归档日志和数据库备份的区别
- sql 字段字符串内容替换
- MYSQL数据库迁移总结
- SQL UPDATE 语句
- SQL基础学习
- SQL Server注释
- ubuntu memcached安装和java中memcached使用demo