Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android開發實例-健康食譜應用(二)

Android開發實例-健康食譜應用(二)

編輯:關於Android編程

 

本系列文章主要介紹如何利用Android開發一個簡單的健康食譜軟件。用到的相關技術如下所示:

提供GridView和ListView的基本使用利用universal-image-loader異步加載網絡圖片通過HttpClient獲取網絡http請求數據滑動分頁加載數據 軟件所用的所有數據均來源於www.2cto.com提供的食譜接口,感謝他們!
軟件文件結構如下所示: data-cke-saved-src=https://www.android5.online/Android/UploadFiles_5356/201702/2017022314293933.png
MainActivity:主界面Acitivity MListActivity:子分類列表Acitivity CListActivity:食譜列表Activity DetailActivity:食譜詳情Activity
MainGridAdapter:主界面食譜分類適配器 CListAdapter:食譜列表適配器 Cook:用於保存食譜信息的pojo
HttpUtils:提供Http請求相關功能 MUtils:提供食譜相關的處理邏輯功能


搜索食譜

我們在主界面提供了搜索食譜功能,當用戶輸入食譜名稱時,軟件將給用戶展現出想要的食譜列表。搜索食譜我們主要用到http://api.yi18.net/cook/search接口。 我們在MUtils方法增加搜索食譜方法:
public static ArrayList 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;
	}
該搜索方法提供了食譜名稱和分頁頁碼參數,便於前端實現分頁刷新功能,因為返回的食譜名稱中包含Html信息,我們將其過濾掉。搜索結果將進入食譜列表界面,界面展示出搜索的結果信息

獲取分類食譜

當用戶點擊某一子分類時,將獲取出分類下的食譜列表,主要用到http://api.yi18.net/cook/list接口
我們在MUtils中增加如下方法:
public static ArrayList 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;
	}
同搜索食譜功能一致,這裡提供page對象,便於提供分頁加載

食譜列表界面

食譜列表界面用於展示匹配相應結果的食譜列表,為了用戶更好的了解食譜,在列表中我們提供縮略圖展示。當用戶搜索食譜或者點擊某一分類時,將進入食譜列表界面。 食譜列表界面最終效果圖如下所示: data-cke-saved-src=https://www.android5.online/Android/UploadFiles_5356/201702/2017022314293966.jpg


每個列表展示出食譜的縮略圖、食譜名稱和食譜涉及的材料。列表布局XML設計如下:
 
    



每個Item的布局clist_item.xml如下所示:

 


我們利用clist_item.xml渲染自定義的ListAdapter,取名CListApdater,其代碼如下所示:
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 List dataList;
	
	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);
	}
}

CListAcitivity同時實現了搜索和分類進入的展示功能,並加入下拉分頁加載,其代碼如下所示:
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;	
	List cList;
	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;
		}
	};
}

從代碼中可以看到,我們通過為ListView定制OnScrollListener來實現滾動的分頁加載邏輯

食譜詳情

食譜詳情用戶展示食譜的詳細信息,用戶可以在詳情裡面看到食物的具體制作方法。 最終效果圖如下所示:
data-cke-saved-src=https://www.android5.online/Android/UploadFiles_5356/201702/2017022314293917.jpg

我們首先在MUtils加上獲取詳情的功能:
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;
	}
	

詳情的布局xml如下所示:


 
        
    

DetailActivity的完整實現代碼如下所示:
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));
		}
	};
}

至此,完整的健康食譜軟件開發完成
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved