转载自:https://i-blog.csdnimg.cn/blog_migrate/2423543f2c42d5f78a588ddf12db177f.png
本系列文章主要介绍如何利用Android开发一个简单的健康食谱软件。用到的相关技术如下所示:
- 提供GridView和ListView的基本使用
- 利用universal-image-loader异步加载网络图片
- 通过HttpClient获取网络http请求数据
- 滑动分页加载数据
软件所用的所有数据均来源于http://doc.yi18.net/cookwendang提供的食谱接口,感谢他们!
软件文件结构如下所示:
MainActivity:主界面Acitivity
MListActivity:子分类列表Acitivity
CListActivity:食谱列表Activity
DetailActivity:食谱详情Activity
MainGridAdapter:主界面食谱分类适配器
CListAdapter:食谱列表适配器
Cook:用于保存食谱信息的pojo
HttpUtils:提供Http请求相关功能
MUtils:提供食谱相关的处理逻辑功能
软件主界面设计开发
主界面主要提供了健康食谱的主分类控件,用户可以选择自己感兴趣的分类进行食谱查看。为了便于用户更好的找到自己需要的食谱,我们提供一个全局搜索功能,用户可以输入关键词搜索自己想要的食谱信息,如:萝卜,将加载出所有与萝卜相关的食谱
主界面最终效果图如下所示:
主界面共分为两大块:全局搜索布局和Grid分类布局,其布局xml如下所示:
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/list_item_bg"
- tools:context=".MainActivity" >
- <RelativeLayout
- android:id="@+id/top_layout"
- android:layout_width="match_parent"
- android:layout_height="160dp"
- android:layout_alignParentTop="true"
- android:background="@drawable/main_top" >
- <TextView
- android:layout_width="match_parent"
- android:layout_height="50dp"
- android:background="@drawable/main_title"
- android:text="@string/app_name"
- android:gravity="center"
- android:textColor="@android:color/white"
- android:textSize="18sp"
- android:layout_alignParentTop="true" >
- </TextView>
- <EditText
- android:id="@+id/main_input"
- android:layout_width="match_parent"
- android:layout_height="40dp"
- android:layout_alignParentBottom="true"
- android:layout_margin="20dp"
- android:background="@drawable/edit_shape"
- android:hint="@string/search_tip"
- android:lines="1"
- android:paddingLeft="32dp"
- android:paddingRight="32dp"
- android:singleLine="true"
- android:textSize="16sp" >
- </EditText>
- <ImageView
- android:id="@+id/main_clear_btn"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignBottom="@+id/main_input"
- android:layout_alignLeft="@+id/main_input"
- android:layout_alignTop="@+id/main_input"
- android:src="@drawable/clear" />
- <ImageView
- android:id="@+id/main_search_btn"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignBottom="@+id/main_input"
- android:layout_alignRight="@+id/main_input"
- android:layout_alignTop="@+id/main_input"
- android:src="@drawable/search" >
- </ImageView>
- </RelativeLayout>
- <GridView
- android:id="@+id/main_grid"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_below="@id/top_layout"
- android:layout_marginTop="20dp"
- android:gravity="center_horizontal"
- android:numColumns="3"
- android:scrollbars="none"
- android:verticalSpacing="20dp" >
- </GridView>
- </RelativeLayout>
- import java.util.List;
- import android.content.Context;
- import android.content.Intent;
- 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;
- public class MainGridAdapter extends BaseAdapter {
- private List<Item> items;
- private Context ctx;
- public MainGridAdapter(List<Item> items, Context ctx) {
- this.items = items;
- this.ctx = ctx;
- }
- @Override
- public int getCount() {
- return items.size();
- }
- @Override
- public Object getItem(int arg0) {
- return items.get(arg0);
- }
- @Override
- public long getItemId(int arg0) {
- return arg0;
- }
- @Override
- public View getView(final int position, View view, ViewGroup arg2) {
- if(view == null) {
- view = LayoutInflater.from(ctx).inflate(R.layout.item, null);
- }
- final Item item = items.get(position);
- ImageView icon = (ImageView) view.findViewById(R.id.item_icon);
- icon.setImageResource(item.icon);
- TextView text = (TextView) view.findViewById(R.id.item_text);
- text.setText(ctx.getString(item.text));
- view.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent();
- intent.putExtra("id", position+1);
- intent.putExtra("title", ctx.getString(item.text));
- intent.setClass(ctx, MListActivity.class);
- ctx.startActivity(intent);
- }
- });
- return view;
- }
- static class Item {
- public Item() {
- }
- public Item(int bgColor, int icon, int text) {
- super();
- this.bgColor = bgColor;
- this.icon = icon;
- this.text = text;
- }
- public int bgColor;
- public int icon;
- public int text;
- }
- }
- view.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent();
- intent.putExtra("id", position+1);
- intent.putExtra("title", ctx.getString(item.text));
- intent.setClass(ctx, MListActivity.class);
- ctx.startActivity(intent);
- }
- });
该Adapter使用方式如下所示:
- private void initGrid() {
- List<Item> items = new ArrayList<Item>();
- items.add(new Item(R.color.item1, R.drawable.item1, R.string.item1));
- items.add(new Item(R.color.item2, R.drawable.item2, R.string.item2));
- items.add(new Item(R.color.item3, R.drawable.item3, R.string.item3));
- items.add(new Item(R.color.item4, R.drawable.item4, R.string.item4));
- items.add(new Item(R.color.item5, R.drawable.item5, R.string.item5));
- items.add(new Item(R.color.item6, R.drawable.item6, R.string.item6));
- items.add(new Item(R.color.item7, R.drawable.item7, R.string.item7));
- items.add(new Item(R.color.item8, R.drawable.item8, R.string.item8));
- items.add(new Item(R.color.item9, R.drawable.item9, R.string.item9));
- items.add(new Item(R.color.item9, R.drawable.item10, R.string.item10));
- items.add(new Item(R.color.item9, R.drawable.item11, R.string.item11));
- items.add(new Item(R.color.item9, R.drawable.item12, R.string.item12));
- items.add(new Item(R.color.item9, R.drawable.item13, R.string.item13));
- items.add(new Item(R.color.item9, R.drawable.item14, R.string.item14));
- grid.setAdapter(new MainGridAdapter(items, this));
- }
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Timer;
- import java.util.TimerTask;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.KeyEvent;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.EditText;
- import android.widget.GridView;
- import android.widget.ImageView;
- import android.widget.Toast;
- public class MainActivity extends Activity implements OnClickListener {
- private GridView grid;
- private ImageView clearButton, searchButton;
- private EditText input;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- clearButton = (ImageView) findViewById(R.id.main_clear_btn);
- clearButton.setOnClickListener(this);
- searchButton = (ImageView) findViewById(R.id.main_search_btn);
- searchButton.setOnClickListener(this);
- input = (EditText) findViewById(R.id.main_input);
- grid = (GridView) findViewById(R.id.main_grid);
- initGrid();
- }
- private void initGrid() {
- List<Item> items = new ArrayList<Item>();
- items.add(new Item(R.color.item1, R.drawable.item1, R.string.item1));
- items.add(new Item(R.color.item2, R.drawable.item2, R.string.item2));
- items.add(new Item(R.color.item3, R.drawable.item3, R.string.item3));
- items.add(new Item(R.color.item4, R.drawable.item4, R.string.item4));
- items.add(new Item(R.color.item5, R.drawable.item5, R.string.item5));
- items.add(new Item(R.color.item6, R.drawable.item6, R.string.item6));
- items.add(new Item(R.color.item7, R.drawable.item7, R.string.item7));
- items.add(new Item(R.color.item8, R.drawable.item8, R.string.item8));
- items.add(new Item(R.color.item9, R.drawable.item9, R.string.item9));
- items.add(new Item(R.color.item9, R.drawable.item10, R.string.item10));
- items.add(new Item(R.color.item9, R.drawable.item11, R.string.item11));
- items.add(new Item(R.color.item9, R.drawable.item12, R.string.item12));
- items.add(new Item(R.color.item9, R.drawable.item13, R.string.item13));
- items.add(new Item(R.color.item9, R.drawable.item14, R.string.item14));
- grid.setAdapter(new MainGridAdapter(items, this));
- }
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.main_clear_btn:
- input.setText("");
- break;
- case R.id.main_search_btn:
- String searchStr = input.getText().toString();
- if(searchStr == null || searchStr.trim().equals("")) {
- Toast.makeText(this, "请输入要搜索的菜谱!", Toast.LENGTH_SHORT).show();
- } else {
- Intent intent = new Intent();
- intent.putExtra("keyword", searchStr);
- intent.setClass(this, CListActivity.class);
- startActivity(intent);
- }
- break;
- default:
- break;
- }
- }
- }
子分类界面设计开发
当用户点击主界面的主分类条目时,将进入该分类的子分类列表界面。子分类接口为:
http://api.yi18.net/cook/cookclass?id=myid
我们在MUtils中提供获取子分类的方法:
- @SuppressWarnings("serial")
- public static ArrayList<HashMap<String, Object>> getChildClass(final int pid) {
- String url = "http://api.yi18.net/cook/cookclass";
- String result = HttpUtils.httpGet(url, new HashMap<String, Object>(){{
- put("id", pid);
- }});
- ArrayList<HashMap<String, Object>> dataMap = new ArrayList<HashMap<String, Object>>();
- 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++) {
- HashMap<String, Object> data = new HashMap<String, Object>();
- JSONObject obj = datas.getJSONObject(i);
- data.put("id", obj.getInt("id"));
- data.put("name", obj.getString("name"));
- dataMap.add(data);
- }
- }
- } catch (Exception e) {
- }
- }
- return dataMap;
- }
返回ArrayList<HashMap>是为了便于SimpleAdapter直接使用,使用见如下的MListActivity中的相关代码:
- import java.util.ArrayList;
- import java.util.HashMap;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.AdapterView;
- import android.widget.AdapterView.OnItemClickListener;
- import android.widget.ImageView;
- import android.widget.ListView;
- import android.widget.SimpleAdapter;
- import android.widget.TextView;
- import com.my.lib.Utils;
- public class MListActivity extends Activity implements OnClickListener, OnItemClickListener, Runnable {
- private ImageView unconnect;
- private ListView mlist;
- Handler handler;
- ArrayList<HashMap<String, Object>> mdata;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.list);
- findViewById(R.id.list_return).setOnClickListener(this);
- mlist = (ListView) findViewById(R.id.mlist);
- mlist.setOnItemClickListener(this);
- unconnect = (ImageView) findViewById(R.id.list_unconnect);
- unconnect.setOnClickListener(this);
- ((TextView)findViewById(R.id.list_title)).setText(getIntent().getStringExtra("title"));
- handler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- if(mdata == null) {
- change(true);
- } else {
- change(false);
- mlist.setAdapter(new SimpleAdapter(MListActivity.this, mdata, R.layout.list_item, new String[]{"name"}, new int[]{R.id.list_item_text}));
- }
- }
- };
- new Thread(this).start();
- }
- @Override
- @SuppressWarnings("unchecked")
- public void onItemClick(AdapterView<?> av, View v, int position, long arg3) {
- HashMap<String, Object> item = (HashMap<String, Object>)av.getItemAtPosition(position);
- Intent intent = new Intent();
- intent.putExtra("id", (Integer)item.get("id"));
- intent.putExtra("title", (String)item.get("name"));
- intent.setClass(this, CListActivity.class);
- startActivity(intent);
- }
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.list_return:
- MListActivity.this.finish();
- break;
- case R.id.list_unconnect:
- new Thread(this).start();
- break;
- default:
- break;
- }
- }
- @Override
- public void run() {
- if(Utils.canAccessNetwork(MListActivity.this)) {
- mdata = MUtils.getChildClass(getIntent().getIntExtra("id", 1));
- }
- handler.sendEmptyMessage(1);
- }
- void change(boolean flag) {
- if(flag) {
- mlist.setVisibility(View.GONE);
- unconnect.setVisibility(View.VISIBLE);
- } else {
- mlist.setVisibility(View.VISIBLE);
- unconnect.setVisibility(View.GONE);
- }
- }
- }
分类列表布局XML如下所示:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/list_item_bg"
- android:orientation="vertical" >
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="50dp"
- android:background="@drawable/title_bg" >
- <ImageView
- android:id="@+id/list_return"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_centerVertical="true"
- android:layout_marginLeft="20dp"
- android:src="@drawable/arrowl" />
- <TextView
- android:id="@+id/list_title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerInParent="true"
- android:textColor="@android:color/white"
- android:textSize="18sp"
- android:textStyle="bold" />
- </RelativeLayout>
- <ListView
- android:id="@+id/mlist"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:scrollbars="none" >
- </ListView>
- <ImageView
- android:id="@+id/list_unconnect"
- android:layout_marginTop="160dp"
- android:layout_gravity="center"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/unconnect"
- android:visibility="gone"/>
- </LinearLayout>
Item布局xml如下所示:
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="50dp"
- android:background="@drawable/list_selector" >
- <ImageView
- android:id="@+id/mlist_item_icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_centerVertical="true"
- android:src="@drawable/list_item_icon"
- android:layout_marginLeft="20dp"
- android:layout_marginRight="20dp" />
- <TextView
- android:id="@+id/list_item_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_toRightOf="@+id/mlist_item_icon"
- android:textColor="@android:color/white"
- android:textSize="16sp" />
- <ImageView
- android:id="@+id/mlist_item_arrow"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/arrowr"
- android:layout_alignParentRight="true"
- android:layout_centerVertical="true"
- android:layout_marginRight="20dp" />
- </RelativeLayout>