編輯:關於Android編程
本系列文章主要介紹如何利用Android開發一個簡單的健康食譜軟件。用到的相關技術如下所示:
提供GridView和ListView的基本使用利用universal-image-loader異步加載網絡圖片通過HttpClient獲取網絡http請求數據滑動分頁加載數據 軟件所用的所有數據均來源於www.2cto.com提供的食譜接口,感謝他們!public static ArrayList該搜索方法提供了食譜名稱和分頁頁碼參數,便於前端實現分頁刷新功能,因為返回的食譜名稱中包含Html信息,我們將其過濾掉。搜索結果將進入食譜列表界面,界面展示出搜索的結果信息search(final String keyword, final int page) { String url = http://api.yi18.net/cook/search; String result = HttpUtils.httpGet(url, new HashMap (){{ put(keyword, URLEncoder.encode(keyword)); put(page, page); put(limit, 20); }}); ArrayList dataMap = new ArrayList (); if(result != null) { try { JSONObject root = new JSONObject(result); if(root.getBoolean(success)) { JSONArray datas = root.getJSONArray(yi18); for(int i = 0, len = datas.length(); i < len; i++) { JSONObject obj = datas.getJSONObject(i); Cook c = new Cook(); c.id = obj.optInt(id); c.name = obj.optString(name); if(c.name != null) { c.name = c.name.replace(, ).replace(, ); } c.food = obj.optString(description); c.img = obj.optString(img); c.tag = obj.optString(keywords); dataMap.add(c); } } } catch (Exception e) { } } return dataMap; }
public static ArrayList同搜索食譜功能一致,這裡提供page對象,便於提供分頁加載getCooks(final int classId, final int page, final int sortType) { String url = http://api.yi18.net/cook/list; String result = HttpUtils.httpGet(url, new HashMap (){{ put(id, classId); put(page, page); put(limit, 20); put(type, sortType == SORT2 ? count : id); }}); ArrayList dataMap = new ArrayList (); if(result != null) { try { JSONObject root = new JSONObject(result); if(root.getBoolean(success)) { JSONArray datas = root.getJSONArray(yi18); for(int i = 0, len = datas.length(); i < len; i++) { JSONObject obj = datas.getJSONObject(i); Cook c = new Cook(); c.id = obj.optInt(id); c.name = obj.optString(name); c.count = obj.optInt(count); c.fcount = obj.optInt(fcount); c.rcount = obj.optInt(rcount); c.food = obj.optString(food); c.img = obj.optString(img); c.tag = obj.optString(tag); dataMap.add(c); } } } catch (Exception e) { } } return dataMap; }
import java.util.List; import android.content.Intent; import android.graphics.Bitmap; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; import com.nostra13.universalimageloader.core.assist.ImageScaleType; public class CListAdapter extends BaseAdapter { private CListActivity activity; private ListdataList; public CListAdapter(CListActivity activity, List dataList) { this.activity = activity; this.dataList = dataList; //初始化Android-Universal-Image-Loader框架 ImageLoader.getInstance().init(ImageLoaderConfiguration.createDefault(activity)); } @Override public int getCount() { return dataList.size(); } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { convertView = LayoutInflater.from(activity).inflate(R.layout.clist_item, null); final Cook c = dataList.get(position); ((TextView)convertView.findViewById(R.id.clist_item_title)).setText(c.name); ((TextView)convertView.findViewById(R.id.clist_item_detail)).setText(c.tag); //設置圖片顯示格式(我們可以設置圓角、緩存等一些列配置) DisplayImageOptions options = new DisplayImageOptions.Builder() .showImageOnLoading(R.drawable.loading) //加載中顯示的正在加載中的圖片 .showImageOnFail(R.drawable.loading) //為了方便,加載失敗也顯示加載中的圖片 .cacheInMemory(true) //在內存中緩存圖片 .cacheOnDisk(true) .bitmapConfig(Bitmap.Config.RGB_565) .imageScaleType(ImageScaleType.EXACTLY) //設置圖片以如何的編碼方式顯示 .build(); //異步加載圖片,並渲染到指定的控件上 ImageLoader.getInstance().displayImage(MUtils.PREFIX_IMG + c.img, (ImageView)convertView.findViewById(R.id.clist_item_icon), options); //Item點擊後進入食譜詳情界面 convertView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(activity, DetailActivity.class); intent.putExtra(id, c.id); intent.putExtra(title, c.name); activity.startActivity(intent); } }); return convertView; } //為Adapter增加新的食譜數據,當分頁加載時,用於更新分頁信息 public void add(List newData) { dataList.addAll(newData); } }
import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Handler.Callback; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; import android.widget.TextView; public class CListActivity extends Activity implements OnClickListener, OnItemClickListener, Runnable { int lastVisibleIndex = 0; //滾動的最後可見條目 int page = 1; //當前分頁頁碼 int cId; //分類ID String keyword; //搜索關鍵詞 CListAdapter mAdapter; ListcList; ListView mlistView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.clist); findViewById(R.id.clist_return).setOnClickListener(this); mlistView = (ListView) findViewById(R.id.clist); mlistView.setOnItemClickListener(this); mlistView.setOnScrollListener(scrollListener); cId = getIntent().getIntExtra(id, 0); if(cId == 0) { //食譜搜索 keyword = getIntent().getStringExtra(keyword); ((TextView)findViewById(R.id.clist_title)).setText(keyword); } else { //分類進入 ((TextView)findViewById(R.id.clist_title)).setText(getIntent().getStringExtra(title)); } cList = new ArrayList (); new Thread(this).start(); } @Override public void onItemClick(AdapterView av, View arg1, int arg2, long arg3) { } @Override public void onClick(View v) { switch (v.getId()) { case R.id.clist_return: CListActivity.this.finish(); break; default: break; } } @Override public void run() { loadData(); handler.sendEmptyMessage(0); } public void loadData() { List results; if(cId == 0) { results = MUtils.search(keyword, page++); } else { results = MUtils.getCooks(cId, page++, MUtils.SORT1); } //獲取成功,則更新數據列表 cList.addAll(results); } Handler handler = new Handler(new Callback() { @Override public boolean handleMessage(Message msg) { //更新列表界面 if(mAdapter == null) { mAdapter = new CListAdapter(CListActivity.this, cList); mlistView.setAdapter(mAdapter); } else { mAdapter.notifyDataSetChanged(); } return false; } }); OnScrollListener scrollListener = new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { int itemsLastIndex = mAdapter.getCount() - 1; // 數據集最後一項的索引 if ((scrollState == SCROLL_STATE_TOUCH_SCROLL || scrollState == SCROLL_STATE_IDLE) && lastVisibleIndex == itemsLastIndex) { //當滾動最後一項時,加載新的一頁數據 new Thread(CListActivity.this).start(); } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { //滾動過程中更新最後可見索引 lastVisibleIndex = firstVisibleItem + visibleItemCount - 1; } }; }
public static Cook show(final int id) { String url = http://api.yi18.net/cook/show; String result = HttpUtils.httpGet(url, new HashMap(){{ put(id, id); }}); if(result != null) { try { JSONObject root = new JSONObject(result); if(root.getBoolean(success)) { JSONObject obj = root.getJSONObject(yi18); Cook c = new Cook(); c.id = obj.optInt(id); c.name = obj.optString(name); c.count = obj.optInt(count); c.fcount = obj.optInt(fcount); c.rcount = obj.optInt(rcount); c.food = obj.optString(food); c.img = obj.optString(img); c.tag = obj.optString(tag); c.message = obj.optString(message); return c; } } catch (Exception e) { } } return null; }
import com.nostra13.universalimageloader.core.ImageLoader; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.text.Html; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageView; import android.widget.TextView; public class DetailActivity extends Activity implements OnClickListener, Runnable { private TextView titleView, contentView, foodView, nameView; private ImageView imgView; private int id; private Cook cook; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.detail); titleView = (TextView) findViewById(R.id.detail_title); contentView = (TextView) findViewById(R.id.detail_text); foodView = (TextView) findViewById(R.id.detail_food); nameView = (TextView) findViewById(R.id.detail_name); imgView = (ImageView) findViewById(R.id.detail_img); findViewById(R.id.detail_return).setOnClickListener(this); initData(); } private void initData() { titleView.setText(getIntent().getStringExtra(title)); id = getIntent().getIntExtra(id, 1); new Thread(this).start(); } @Override public void run() { cook = MUtils.show(id); handler.sendEmptyMessage(0); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.detail_return: DetailActivity.this.finish(); break; default: break; } } Handler handler = new Handler() { @Override public void handleMessage(Message msg) { //異步顯示圖片 ImageLoader.getInstance().displayImage(MUtils.PREFIX_IMG + cook.img, imgView); nameView.setText(cook.name); foodView.setText(cook.food); //內容以Html的方式展示 contentView.setText(Html.fromHtml(cook.message)); } }; }
本文實例介紹了Android中LinearLayout、AbsoluteLayout的用法,希望能對於初學Android的朋友起到一點幫助作用。具體內容如下:Androi
啟動模式一共有四種,分別是 standard、singleTop、singleTask 和 singleInstance , 可 以 在 AndroidManifest
activity類 package com.kane.listview; import java.util.ArrayList; import java.util.D
關於Android View 事件分發過程的文章網絡上可以搜到一把大,這裡貼一篇代碼性的文章,作者也是個牛人:Android事件分發機制完全解析,帶你從源碼的角度徹底理解