編輯:關於Android編程
首先還是來把總體的編碼流程來樹梳理一下,按照這個順序來編碼可以使思路更加清晰。
(1)創建兩個View,一個listview一個item_view
(2)根據view的id來找到listview
(3)從數據庫獲得數據
<1>創建一個包含News數據信息的bean,bean中包含image、title、url和content等
<2>有了news的bean就應該有操作bean的Utils,這裡創建一個NewsUtils類
<3>NewsUtils的作用就是獲取新聞數據的,裡面主要有兩個方法:getAllNewsForNetWork和getAllNewsForDatabase
<4>網絡那個後面說,從數據庫中得到首先要有數據庫和他的操作類,創建NewsOpenHelper和NewsDaoUtils
<5>NewsOpenHelper是數據庫的幫助類,NewsDaoUtils中定義增刪改查的方法
<6>流程是NewsUtils.getAllNewsForDatabase()->NewsDaoUtils.getNews()
(4)將數據傳給item_view並做顯示
<1>通過上面的步驟得到ArrayList
<2>ListView使用要通過一個Adapter類,我們定義一個NewsAdapter類並實現其四個覆寫BaseAdapter的四個方法
<3>在NewsAdapter中的getView()中將我們定義好的item_view布局並將其轉換成一個view,並根據面得到的數據來給view
的各個控件賦值
(5)從網絡端獲取數據,並將數據庫中的數據更新
<1>上面也提到了,通過網絡獲取數據,在NewsUtils中定義getAllNewsForNewWork
<2>也就是通過網絡訪問服務器中GetNewsServlet,實現輸入流和輸出流的對接,當然這邊是輸入流了
<3>將得到的流通過StreamUtils.streamToString()轉化成字符串
<4>因為數據是json格式的,所以需要先轉化成json對象再進行解析,最終編程ArrayList
<5>注意在返回數據之前,先將數據庫清空,然後將數據緩存到裡邊
<6>回到主函數,因為主線程中不能處理時間過長的時間,所以要建立一個子線程獲取網絡數據
<7>建立一個主線程來進行ListView的展示
(6)當有事件點擊時的跳轉
<1>當有點擊事件時,跳轉到news_url
(7)smartimageview 的原理
<1>自定義了一個MyImageview類繼承了Imageview,添加三個構造方法
<2>添加一個setImageUrl方法接受一個圖片url
<3>新建一個子線程去請求url獲取圖片資源
<4>將獲取的圖片Bitmap通過handler發送給主線程,主線程設置給當前view
<5>在布局中引用MyImageview,需要指定完成的包名路徑。
Activity中就只有一個ListView就不展示了,下面是item_news_layout.xml 的代碼
使用線性和相對布局相結合的方式了就行布局,包括標題、內容、圖片和評論等
(1)創建一個包含News數據信息的bean,bean中包含image、title、url和content等
package com.iigt.Internews.bean; public class NewsBean { public String title; public String des; public String news_url; public int id; public int comment; public int type; public String time; public String icon_url; }
(2)有了news的bean就應該有操作bean的Utils,這裡創建一個NewsUtils類
package com.iigt.Internews.utils; public class NewsUtils { public static String newsPath_url = "http://115.25.200.156:8080/itheima74/servlet/GetNewsServlet"; //封裝新聞的假數據到list中返回 public static ArrayList(3)NewsUtils的作用就是獲取新聞數據的,裡面主要有兩個方法:getAllNewsForNetWork和getAllNewsForDatabasegetAllNewsForNetWork(Context context) //從數據庫中獲取上次緩存的新聞數據做listview的展示 public static ArrayList getAllNewsForDatabase(Context context) }
//從數據庫中獲取上次緩存的新聞數據做listview的展示 public static ArrayListgetAllNewsForDatabase(Context context) { return new NewsDaoUtils(context).getNews(); }
package com.iigt.Internews.dao; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; public class NewsOpenHelper extends SQLiteOpenHelper { public NewsOpenHelper(Context context) { super(context, "heimanews1", null, 1); } @Override public void onCreate(SQLiteDatabase db) { /* newsJson.put("id", newsBean.getId()); newsJson.put("title", newsBean.getTitle()); newsJson.put("des", newsBean.getDes()); newsJson.put("icon_url", newsBean.getIcon_url()); newsJson.put("news_url", newsBean.getNews_url()); newsJson.put("type", newsBean.getType()); newsJson.put("time", newsBean.getTime()); newsJson.put("comment", newsBean.getComment());*/ db.execSQL("create table news (_id integer ,title varchar(200),des varchar(300),icon_url varchar(200),news_url varchar(200)," + " type integer , time varchar(100),comment integer)"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub } }
package com.iigt.Internews.dao; import java.util.ArrayList; import com.iigt.Internews.bean.NewsBean; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; public class NewsDaoUtils { private NewsOpenHelper newsOpenHelper; public NewsDaoUtils(Context context){ //創建一個幫助類對象 newsOpenHelper = new NewsOpenHelper(context); } //刪除數據庫中緩存的舊數據 public void delete(){ //通過幫助類對象獲取一個數據庫操作對象 SQLiteDatabase db = newsOpenHelper.getReadableDatabase(); db.delete("news", null, null); db.close(); } //向數據庫中添加新聞數據 public void saveNews(ArrayList其獲取數據的流程是NewsUtils.getAllNewsForDatabase()->NewsDaoUtils.getNews()list){ //通過幫助類對象獲取一個數據庫操作對象 SQLiteDatabase db = newsOpenHelper.getReadableDatabase(); for (NewsBean newsBean : list) { ContentValues values = new ContentValues(); values.put("_id", newsBean.id); values.put("title", newsBean.title); values.put("des", newsBean.des); values.put("icon_url", newsBean.icon_url); values.put("news_url", newsBean.news_url); values.put("type", newsBean.type); values.put("time", newsBean.time); values.put("comment", newsBean.comment); db.insert("news", null, values); } db.close(); } //從數據庫中獲取緩存的新聞數據 public ArrayList getNews(){ ArrayList list = new ArrayList (); //通過幫助類對象獲取一個數據庫操作對象 SQLiteDatabase db = newsOpenHelper.getReadableDatabase(); Cursor cursor = db.rawQuery("select * from news", null);//查詢獲取數據 if(cursor != null && cursor.getCount() > 0){ while(cursor.moveToNext()){ NewsBean newsBean = new NewsBean(); newsBean. id = cursor.getInt(0); newsBean. title = cursor.getString(1); newsBean. des = cursor.getString(2); newsBean. icon_url = cursor.getString(3); newsBean. news_url = cursor.getString(4); newsBean. type = cursor.getInt(5); newsBean. time = cursor.getString(6); newsBean. comment = cursor.getInt(7); list.add(newsBean); } } db.close(); cursor.close(); return list; } }
(1)通過上面的步驟得到ArrayList
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mContext = this; lv_news = (ListView) findViewById(R.id.lv_news); //1.先去數據庫中獲取緩存的新聞數據展示到listview ArrayListallnews_database = NewsUtils.getAllNewsForDatabase(mContext); if(allnews_database !=null && allnews_database.size()>0){ //創建一個adapter設置給listview NewsAdapter newsAdapter = new NewsAdapter(mContext, allnews_database); lv_news.setAdapter(newsAdapter); }
package com.iigt.Internews.adapter; import java.util.ArrayList; import com.iigt.Internews.R; import com.iigt.Internews.bean.NewsBean; import com.iigt.Internews.view.MyImageView; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; public class NewsAdapter extends BaseAdapter { private ArrayList在NewsAdapter中的getView()中將我們定義好的item_view布局並將其轉換成一個view,並根據面得到的數據來給viewlist; private Context context; //通過構造方法接受要顯示的新聞數據集合 public NewsAdapter(Context context,ArrayList list){ this.list = list; this.context = context; } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { View view = null; //1.復用converView優化listview,創建一個view作為getview的返回值用來顯示一個條目 if(convertView != null){ view = convertView; }else { //context:上下文, resource:要轉換成view對象的layout的id, root:將layout用root(ViewGroup)包一層作為codify的返回值,一般傳null // view = View.inflate(context, R.layout.item_news_layout, null);//將一個布局文件轉換成一個view對象 //通過LayoutInflater將布局轉換成view對象 // view = LayoutInflater.from(context).inflate(R.layout.item_news_layout, null); //通過context獲取系統服務得到一個LayoutInflater,通過LayoutInflater將一個布局轉換為view對象 LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = layoutInflater.inflate(R.layout.item_news_layout, null); } //2.獲取view上的子控件對象 MyImageView item_img_icon = (MyImageView) view.findViewById(R.id.item_img_icon); TextView item_tv_des = (TextView) view.findViewById(R.id.item_tv_des); TextView item_tv_title = (TextView) view.findViewById(R.id.item_tv_title); TextView item_tv_comment = (TextView) view.findViewById(R.id.item_tv_comment); TextView item_tv_type = (TextView) view.findViewById(R.id.item_tv_type); //3.獲取postion位置條目對應的list集合中的新聞數據,Bean對象 NewsBean newsBean = list.get(position); //4.將數據設置給這些子控件做顯示 item_img_icon.setImageUrl(newsBean.icon_url); item_tv_title.setText(newsBean.title); item_tv_des.setText(newsBean.des); item_tv_comment.setText("評論:"+newsBean.comment); //0 :頭條 1 :娛樂 2.體育 switch (newsBean.type) { case 0: item_tv_type.setText("頭條"); break; case 1: item_tv_type.setText("娛樂 "); break; case 2: item_tv_type.setText("體育"); break; default: break; } return view; } }
的各個控件賦值
(1)上面也提到了,通過網絡獲取數據,在NewsUtils中定義getAllNewsForNewWork
public static String newsPath_url = "http://115.25.200.156:8080/itheima74/servlet/GetNewsServlet"; //封裝新聞的假數據到list中返回 public static ArrayListgetAllNewsForNetWork(Context context) { ArrayList arrayList = new ArrayList (); try{ //1.請求服務器獲取新聞數據 //獲取一個url對象,通過url對象得到一個urlconnnection對象 URL url = new URL(newsPath_url); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); //設置連接的方式和超時時間 connection.setRequestMethod("GET"); connection.setConnectTimeout(10*1000); //獲取請求響應碼 int code = connection.getResponseCode(); if(code == 200){ //獲取請求到的流信息 InputStream inputStream = connection.getInputStream(); //將流轉換成字符串 String result = StreamUtils.streamToString(inputStream); //2.解析獲取的新聞數據到List集合中。 JSONObject root_json = new JSONObject(result);//將一個字符串封裝成一個json對象。 JSONArray jsonArray = root_json.getJSONArray("newss");//獲取root_json中的newss作為jsonArray對象 for (int i = 0 ;i < jsonArray.length();i++){//循環遍歷jsonArray JSONObject news_json = jsonArray.getJSONObject(i);//獲取一條新聞的json NewsBean newsBean = new NewsBean(); newsBean. id = news_json.getInt("id"); newsBean. comment = news_json.getInt("comment");//評論數 newsBean. type = news_json.getInt("type");//新聞的類型,0 :頭條 1 :娛樂 2.體育 newsBean. time = news_json.getString("time"); newsBean. des = news_json.getString("des"); newsBean. title = news_json.getString("title"); newsBean. news_url = news_json.getString("news_url"); newsBean. icon_url = news_json.getString("icon_url"); arrayList.add(newsBean); } //3.清除數據庫中舊的數據,將新的數據緩存到數據庫中 new NewsDaoUtils(context).delete(); new NewsDaoUtils(context).saveNews(arrayList); } }catch (Exception e) { e.printStackTrace(); } return arrayList; }
package com.itheima.service; import java.io.IOException; import java.sql.*; import java.util.ArrayList; public class GetNewsServlet extends HttpServlet { // 構造方法 public GetNewsServlet() { super(); } // 摧毀這個servlet,不太懂 public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try{ ArrayListnews = NewsDao.getNews(); JSONArray jsonArray = new JSONArray(); for (NewsBean newsBean : news) { JSONObject newsJson = new JSONObject(); newsJson.put("id", newsBean.getId()); newsJson.put("title", newsBean.getTitle()); newsJson.put("des", newsBean.getDes()); newsJson.put("icon_url", newsBean.getIcon_url()); newsJson.put("news_url", newsBean.getNews_url()); newsJson.put("type", newsBean.getType()); newsJson.put("time", newsBean.getTime()); newsJson.put("comment", newsBean.getComment()); jsonArray.put(newsJson); } JSONObject allNewsJson = new JSONObject(); allNewsJson.put("newss", jsonArray); response.getOutputStream().write(allNewsJson.toString().getBytes("gbk")); }catch (Exception e) { } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } public void init() throws ServletException { } }
public class StreamUtils { public static String streamToString(InputStream in){ String result =""; try{ //創建一個字節數組寫入流 ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int length = 0; while ( (length = in.read(buffer)) !=-1) { out.write(buffer, 0, length); out.flush(); } result = new String(out.toByteArray(),"gbk"); // result = out.toString();//將字節流轉換成string out.close(); }catch (Exception e) { e.printStackTrace(); } return result; } }因為數據是json格式的,所以需要先轉化成json對象再進行解析,最終編程ArrayList
(5)注意在返回數據之前,先將數據庫清空,然後將數據緩存到裡邊
//3.清除數據庫中舊的數據,將新的數據緩存到數據庫中 new NewsDaoUtils(context).delete(); new NewsDaoUtils(context).saveNews(arrayList);
//2.通過網絡獲取服務器上的新聞數據用list封裝 ,獲取網絡數據需要在子線程中做 new Thread(new Runnable() { @Override public void run() { //請求網絡數據 ArrayListallNews = NewsUtils.getAllNewsForNetWork(mContext); //通過handler將msg發送到主線程去更新Ui Message msg = Message.obtain(); msg.obj = allNews; handler.sendMessage(msg); } }).start();
private Handler handler = new Handler(){ public void handleMessage(android.os.Message msg) { ArrayListallNews = (ArrayList ) msg.obj; if(allNews != null && allNews .size()>0) { //3.創建一個adapter設置給listview NewsAdapter newsAdapter = new NewsAdapter(mContext, allNews); lv_news.setAdapter(newsAdapter); } }; };
點擊事件處理函數
public void onItemClick(AdapterView parent, View view, int position, long id) { //需要獲取條目上bean對象中url做跳轉 NewsBean bean = (NewsBean) parent.getItemAtPosition(position); String url = bean.news_url; //跳轉浏覽器 Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setData(Uri.parse(url)); startActivity(intent); }
public class MyImageView extends ImageView { public MyImageView(Context context) { super(context); } public MyImageView(Context context, AttributeSet attrs) { super(context, attrs); } public MyImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } private Handler handler = new Handler(){ public void handleMessage(android.os.Message msg) { Bitmap bitmap = (Bitmap) msg.obj; MyImageView.this.setImageBitmap(bitmap); }; }; public void setImageUrl(final String url_str){ new Thread(new Runnable() { @Override public void run() { try{ //獲取url對應的圖片資源,bitmap URL url = new URL(url_str); HttpURLConnection openConnection = (HttpURLConnection) url.openConnection(); openConnection.setRequestMethod("GET"); openConnection.setConnectTimeout(10*1000); int code = openConnection.getResponseCode(); if(code == 200){ InputStream inputStream = openConnection.getInputStream(); Bitmap bitmap = BitmapFactory.decodeStream(inputStream); Message msg = Message.obtain(); msg.obj = bitmap; handler.sendMessage(msg); } }catch (Exception e) { e.printStackTrace(); } } }).start(); } }
小米手環2和唯樂now2哪個好?小米手環2准備開放購買了,小編了解到,還有一款唯樂now2可以選擇,如果買不到小米手環2的網友,也可以考慮唯樂手環,那麼小米
一.前言第一次做導航時,並沒有關注語音播報,今天特意把這個功能完善一下。但是發現關於語音播報的實現也遇到了一些問題,在官方的討論區也發現關於語音播報的問題特別多,問題基本
Android插件化之資源動態加載一.概述Android插件化的一個重要問題就是插件資源訪問問題,先列出會面對的問題1.如何加載插件資源2.如何處理插件資源與宿主資源的處
上一篇博客中我們已經繪制出了一個直角三角形,雖然我們相對於坐標,我們設置的直角三角形的兩腰是相等的,但是實際上展示出來的卻並不是這樣,雖然通過計算,我們可以把三角形的兩腰