zoukankan      html  css  js  c++  java
  • Android开发实例-健康食谱应用(一)

    转载请注明出处:http://blog.csdn.net/einarzhang/article/details/44774635

    本系列文章的重点是如何使用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>

    通过 http://api.yi18.net/cook/cookclass接口能够获取到全部的主分类信息。

    我们通过定制自有的MainGridAdapter实现GridView的渲染。源代码例如以下所看到的:

    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;
    	}
    
    }
    当中Item为保存了背景图、分类图标和分类名称的模型对象。

    我们为了实现方便。将背景图忽略。

    MainGridAdapter为每一个分类提供了单击事件。点击后将进入子分类列表:

    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));
        }
    以下给出主界面Activity:
    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); } } }

    须要注意的是:Http请求处理不能在主线程中调用,须要开启新的线程调用。子分类点击后将进入该子分类的食谱列表

    分类列表布局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>






    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    tensorflow1版本和2版本语句兼容
    Tensorflow暑期实践——基于多隐层神经网络的手写数字识别(全部代码+tensorboard可视化)
    Tensorflow暑期实践——基于多隐层神经网络的手写数字识别
    Tensorflow暑期实践——基于单个神经元的手写数字识别(全部代码)
    Tensorflow暑期实践——波士顿房价预测(全部代码)
    Tensorflow暑期实践——基于单个神经元的手写数字识别
    Tensorflow暑期实践——波士顿房价预测
    (1)什么是自动化测试框架
    c++11关键字noexcept
    CTK-使用ctk框架完成日志、打印、界面插件
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/4907448.html
Copyright © 2011-2022 走看看