Android开发-营养成分查询Demo(1)前言-AndroidStudio
2017-04-28 09:42
246 查看
转载请注明出处:http://blog.csdn.net/iwanghang/article/details/70882420
觉得博文有用,请点赞,请评论,请关注,谢谢!~
之前公司有个洽谈的项目,需要用到一个查询食品营养成分的功能,百度了一下没有相关的开放API。
没办法了,那就找相关网站,解析XML了吧。
另外,甲方还要求显示成分百分比,正是这一点,吸引我在工作之余做了Demo进行练习。
下面,我会用演示一下Demo是如何一步一步进行实现的。
![](http://img.blog.csdn.net/20170428093507069?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXdhbmdoYW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
MainActivity.java:
package com.iwanghang.booheesearchdemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
// 显示食物的ListAdapter
private FoodListAdapter foodListAdapter;
// 显示食物的Lis
private ListView listView_food;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView_food = (ListView) findViewById(R.id.listView_food);
sendRequestForListData();
}
private void sendRequestForListData() {
try {
final SocketConnAsync socketConnAsync = new SocketConnAsync();
socketConnAsync.execute(Constant.MALINGSHU);
socketConnAsync.setOnAsyncResponse(new AsyncResponse() {
@Override
public void onDataReceivedSuccess(ArrayList<SearchResult> searchResults) {
System.out.println("onDataReceivedSuccess");
System.out.println("searchResults:" + searchResults);
foodListAdapter = new FoodListAdapter(getApplication(),searchResults);
listView_food.setAdapter(foodListAdapter);
}
@Override
public void onDataReceivedFailed() {
Toast.makeText(MainActivity.this, "data received failed!", Toast.LENGTH_SHORT).show();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
FoodListAdapter.java:
package com.iwanghang.booheesearchdemo;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.ArrayList;
public class FoodListAdapter extends BaseAdapter {
private Context ctx; // 上下文对象引用
private ArrayList<SearchResult> searchResults;// 存放SearchResult引用的集合
private SearchResult searchResult; // SearchResult对象引用
/**
* 构造函数
* @param ctx 上下文
* @param searchResults 集合对象
*/
public FoodListAdapter(Context ctx, ArrayList<SearchResult> searchResults){
this.ctx = ctx;
this.searchResults = searchResults;
//System.out.println("MyMusicListAdapter.java #0 : ctx = " + ctx + ",mp3Infos = " + mp3Infos.size());
}
public ArrayList<SearchResult> searchResults() {
System.out.println("FoodListAdapter.java #1 : public ArrayList<SearchResult> searchResults() {");
return searchResults;
}
public void setSearchResults(ArrayList<SearchResult> searchResults) {
System.out.println("FoodListAdapter.java #2 : public void setMp3Infos(ArrayList<SearchResult> searchResults) {");
this.searchResults = searchResults;
}
public ArrayList<SearchResult> getSearchResults() {
return searchResults;
}
@Override
public int getCount() {
//System.out.println("FoodListAdapter.java #3 : public int getCount() {" + mp3Infos.size());
//return mp3Infos.size();
return searchResults.size();
}
@Override
public Object getItem(int position) {
System.out.println("FoodListAdapter.java #4 : public Object getItem(int position) {");
return searchResults.get(position);
}
@Override
public long getItemId(int position) {
//System.out.println("FoodListAdapter.java #5 : public long getItemId(int position) {");
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//System.out.println("FoodListAdapter.java #6 : public View getView ");
ViewHolder vh;
if(convertView==null){
//vh = new ViewHolder();
convertView = LayoutInflater.from(ctx).inflate(R.layout.item_food_list,null);
vh = new ViewHolder();
vh.tv_foodName = (TextView) convertView.findViewById(R.id.tv_foodName);
vh.tv_kaLuli = (TextView) convertView.findViewById(R.id.tv_kaLuli);
//vh.textView3_time = (TextView) convertView.findViewById(R.id.textView3_time);
//vh.imageView1_ablum = (ImageView) convertView.findViewById(R.id.imageView1_ablum);
//System.out.println("NetMusicListAdapter.java #7 : textView1_title = " + vh.textView1_title);
convertView.setTag(vh);//表示给View添加一个格外的数据,
}else {
vh = (ViewHolder)convertView.getTag();//通过getTag的方法将数据取出来
}
SearchResult searchResult = searchResults.get(position);
vh.tv_foodName.setText(searchResult.getFoodName()); // 显示 食物
vh.tv_kaLuli.setText(searchResult.getFoodKa()); // 显示 卡路里
return convertView;
}
/**
* 定义一个内部类
* 声明相应的控件引用
*/
static class ViewHolder{
// 所有控件对象引用
TextView tv_foodName; // 食物
TextView tv_kaLuli; // 卡路里
}
}
SearchResult.java:
package com.iwanghang.booheesearchdemo;
public class SearchResult {
private String foodName;
private String foodPic;
private String foodUrl;
private String foodKa; // 卡路里
// set方法,get方法
public String getFoodName() {
return foodName;
}
public void setFoodName(String foodName) {
this.foodName = foodName;
}
public String getFoodPic() {
return foodPic;
}
public void setFoodPic(String foodPic) {
this.foodPic = foodPic;
}
public String getFoodUrl() {
return foodUrl;
}
public void setFoodUrl(String foodUrl) {
this.foodUrl = foodUrl;
}
public String getFoodKa() {
return foodKa;
}
public void setFoodKa(String foodKa) {
this.foodKa = foodKa;
}
@Override
public String toString() {
return "SearchResult{" +
"foodName='" + foodName + '\'' +
", foodPic='" + foodPic + '\'' +
", foodUrl='" + foodUrl + '\'' +
", foodKa='" + foodKa + '\'' +
'}';
}
}
SocketConnAsync.java:
package com.iwanghang.booheesearchdemo;
import android.os.AsyncTask;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.util.ArrayList;
class SocketConnAsync extends AsyncTask<String,Integer,Integer> {
// 存放 食物 的 集合
private ArrayList<SearchResult> searchResults = new ArrayList<SearchResult>();
// AsyncResponse 接口回调
public AsyncResponse asyncResponse;
public void setOnAsyncResponse(AsyncResponse asyncResponse)
{
this.asyncResponse = asyncResponse;
}
@Override
protected Integer doInBackground(String... params) {
String url = params[0];
try {
// url = "http://music.migu.cn/webfront/searchNew/searchAll.do?keyword=%E5%88%98%E5%BE%B7%E5%8D%8E&keytype=all&pagesize=20&pagenum=1";
// 使用Jsoup组件请求网络,并解析食物数据
Document doc = Jsoup.connect(url).userAgent(Constant.USER_AGENT).timeout(3000).get();
System.out.println("start**********doc**********doc**********doc**********");
System.out.println(doc);
System.out.println(" end **********doc**********doc**********doc**********");
Elements songTitles = doc.select("li.item.clearfix");
System.out.println("songTitles" + songTitles);
for (int i=0;i<songTitles.size();i++){
SearchResult searchResult = new SearchResult();
Elements urls = songTitles.get(i).getElementsByTag("img");
searchResult.setFoodName(urls.get(0).attr("alt")); // 食物名称 1
searchResult.setFoodPic(urls.get(0).attr("src")); // 食物图片 2
Elements urls2 = songTitles.get(i).getElementsByTag("a");
searchResult.setFoodUrl(Constant.BOHE_HOME_PAGE + urls2.get(0).attr("href")); // 食物连接 3
//searchResult.setFoodKa(songTitles.get(i).getElementsByTag("p").toString()); // 卡路里 4
// kaluli_pp 带2个p标签 kaluli_p 带1个p标签 kaluli 带0个p标签
String kaluli_pp = songTitles.get(i).getElementsByTag("p").toString(); // <p>热量:77 大卡(每100克)</p>
String kaluli_p = kaluli_pp.replace("<p>", ""); // 替换掉<p>
String kaluli = kaluli_p.replace("</p>", ""); // 替换掉</p>
searchResult.setFoodKa(kaluli); // 卡路里 4
System.out.println("MainActivity@searchResult : " + searchResult);
searchResults.add(searchResult);//把最终的所有信息,添加到集合
}
System.out.println("MainActivity@searchResults : " + searchResults);
//System.out.println("@songTitles.size() : " + searchResults.size());
} catch (IOException e) {
e.printStackTrace();
return -1;
}
return 1;
}
// onPostExecute方法用于在执行完后台任务后更新UI,显示结果
@Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
if (result==1){
asyncResponse.onDataReceivedSuccess(searchResults);// 将结果传给回调接口中的函数
}else {
asyncResponse.onDataReceivedFailed();
}
}
}AsyncResponse.java:
package com.iwanghang.booheesearchdemo;
import java.util.ArrayList;
public interface AsyncResponse {
void onDataReceivedSuccess(ArrayList<SearchResult> searchResults);
void onDataReceivedFailed();
}activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.iwanghang.booheesearchdemo.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="食物卡路里一期Demo by iwanghang" />
<ListView
android:id="@+id/listView_food"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:cacheColorHint="@android:color/transparent"
android:listSelector="@android:color/transparent"
android:overScrollMode="never"
android:scrollbars="none"
android:visibility="visible"/>
</LinearLayout>
item_food_list.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">
<ImageView
android:id="@+id/iv_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/food_32px"
android:layout_marginRight="10dp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginRight="10dp"
android:orientation="vertical">
<TextView
android:id="@+id/tv_foodName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:text="tv_foodName" />
<TextView
android:id="@+id/tv_kaLuli"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#a6a8a8"
android:text="tv_kaLuli"/>
</LinearLayout>
<ImageView
android:id="@+id/iv_details"
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@drawable/local_food_more"/>
</LinearLayout>
项目下载:http://download.csdn.net/detail/iwanghang/9828141
转载请注明出处:http://blog.csdn.net/iwanghang/article/details/70882420
欢迎移动开发爱好者交流
沈阳或周边城市公司有意开发Android,请与我联系
联系方式
![](http://img.blog.csdn.net/20161116143246150)
微信:iwanghang
QQ:413711276
邮箱:iwanghang@qq.com
觉得博文有用,请点赞,请评论,请关注,谢谢!~
觉得博文有用,请点赞,请评论,请关注,谢谢!~
之前公司有个洽谈的项目,需要用到一个查询食品营养成分的功能,百度了一下没有相关的开放API。
没办法了,那就找相关网站,解析XML了吧。
另外,甲方还要求显示成分百分比,正是这一点,吸引我在工作之余做了Demo进行练习。
下面,我会用演示一下Demo是如何一步一步进行实现的。
随便找个关键词搜索,比如马铃薯,从浏览器复制url,进行xml解析,显示到列表,显示出来一些基本信息,我们的第一步就算完成,如下图:项目下载:http://download.csdn.net/detail/iwanghang/9828141
MainActivity.java:
package com.iwanghang.booheesearchdemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
// 显示食物的ListAdapter
private FoodListAdapter foodListAdapter;
// 显示食物的Lis
private ListView listView_food;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView_food = (ListView) findViewById(R.id.listView_food);
sendRequestForListData();
}
private void sendRequestForListData() {
try {
final SocketConnAsync socketConnAsync = new SocketConnAsync();
socketConnAsync.execute(Constant.MALINGSHU);
socketConnAsync.setOnAsyncResponse(new AsyncResponse() {
@Override
public void onDataReceivedSuccess(ArrayList<SearchResult> searchResults) {
System.out.println("onDataReceivedSuccess");
System.out.println("searchResults:" + searchResults);
foodListAdapter = new FoodListAdapter(getApplication(),searchResults);
listView_food.setAdapter(foodListAdapter);
}
@Override
public void onDataReceivedFailed() {
Toast.makeText(MainActivity.this, "data received failed!", Toast.LENGTH_SHORT).show();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
FoodListAdapter.java:
package com.iwanghang.booheesearchdemo;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.ArrayList;
public class FoodListAdapter extends BaseAdapter {
private Context ctx; // 上下文对象引用
private ArrayList<SearchResult> searchResults;// 存放SearchResult引用的集合
private SearchResult searchResult; // SearchResult对象引用
/**
* 构造函数
* @param ctx 上下文
* @param searchResults 集合对象
*/
public FoodListAdapter(Context ctx, ArrayList<SearchResult> searchResults){
this.ctx = ctx;
this.searchResults = searchResults;
//System.out.println("MyMusicListAdapter.java #0 : ctx = " + ctx + ",mp3Infos = " + mp3Infos.size());
}
public ArrayList<SearchResult> searchResults() {
System.out.println("FoodListAdapter.java #1 : public ArrayList<SearchResult> searchResults() {");
return searchResults;
}
public void setSearchResults(ArrayList<SearchResult> searchResults) {
System.out.println("FoodListAdapter.java #2 : public void setMp3Infos(ArrayList<SearchResult> searchResults) {");
this.searchResults = searchResults;
}
public ArrayList<SearchResult> getSearchResults() {
return searchResults;
}
@Override
public int getCount() {
//System.out.println("FoodListAdapter.java #3 : public int getCount() {" + mp3Infos.size());
//return mp3Infos.size();
return searchResults.size();
}
@Override
public Object getItem(int position) {
System.out.println("FoodListAdapter.java #4 : public Object getItem(int position) {");
return searchResults.get(position);
}
@Override
public long getItemId(int position) {
//System.out.println("FoodListAdapter.java #5 : public long getItemId(int position) {");
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//System.out.println("FoodListAdapter.java #6 : public View getView ");
ViewHolder vh;
if(convertView==null){
//vh = new ViewHolder();
convertView = LayoutInflater.from(ctx).inflate(R.layout.item_food_list,null);
vh = new ViewHolder();
vh.tv_foodName = (TextView) convertView.findViewById(R.id.tv_foodName);
vh.tv_kaLuli = (TextView) convertView.findViewById(R.id.tv_kaLuli);
//vh.textView3_time = (TextView) convertView.findViewById(R.id.textView3_time);
//vh.imageView1_ablum = (ImageView) convertView.findViewById(R.id.imageView1_ablum);
//System.out.println("NetMusicListAdapter.java #7 : textView1_title = " + vh.textView1_title);
convertView.setTag(vh);//表示给View添加一个格外的数据,
}else {
vh = (ViewHolder)convertView.getTag();//通过getTag的方法将数据取出来
}
SearchResult searchResult = searchResults.get(position);
vh.tv_foodName.setText(searchResult.getFoodName()); // 显示 食物
vh.tv_kaLuli.setText(searchResult.getFoodKa()); // 显示 卡路里
return convertView;
}
/**
* 定义一个内部类
* 声明相应的控件引用
*/
static class ViewHolder{
// 所有控件对象引用
TextView tv_foodName; // 食物
TextView tv_kaLuli; // 卡路里
}
}
SearchResult.java:
package com.iwanghang.booheesearchdemo;
public class SearchResult {
private String foodName;
private String foodPic;
private String foodUrl;
private String foodKa; // 卡路里
// set方法,get方法
public String getFoodName() {
return foodName;
}
public void setFoodName(String foodName) {
this.foodName = foodName;
}
public String getFoodPic() {
return foodPic;
}
public void setFoodPic(String foodPic) {
this.foodPic = foodPic;
}
public String getFoodUrl() {
return foodUrl;
}
public void setFoodUrl(String foodUrl) {
this.foodUrl = foodUrl;
}
public String getFoodKa() {
return foodKa;
}
public void setFoodKa(String foodKa) {
this.foodKa = foodKa;
}
@Override
public String toString() {
return "SearchResult{" +
"foodName='" + foodName + '\'' +
", foodPic='" + foodPic + '\'' +
", foodUrl='" + foodUrl + '\'' +
", foodKa='" + foodKa + '\'' +
'}';
}
}
SocketConnAsync.java:
package com.iwanghang.booheesearchdemo;
import android.os.AsyncTask;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.util.ArrayList;
class SocketConnAsync extends AsyncTask<String,Integer,Integer> {
// 存放 食物 的 集合
private ArrayList<SearchResult> searchResults = new ArrayList<SearchResult>();
// AsyncResponse 接口回调
public AsyncResponse asyncResponse;
public void setOnAsyncResponse(AsyncResponse asyncResponse)
{
this.asyncResponse = asyncResponse;
}
@Override
protected Integer doInBackground(String... params) {
String url = params[0];
try {
// url = "http://music.migu.cn/webfront/searchNew/searchAll.do?keyword=%E5%88%98%E5%BE%B7%E5%8D%8E&keytype=all&pagesize=20&pagenum=1";
// 使用Jsoup组件请求网络,并解析食物数据
Document doc = Jsoup.connect(url).userAgent(Constant.USER_AGENT).timeout(3000).get();
System.out.println("start**********doc**********doc**********doc**********");
System.out.println(doc);
System.out.println(" end **********doc**********doc**********doc**********");
Elements songTitles = doc.select("li.item.clearfix");
System.out.println("songTitles" + songTitles);
for (int i=0;i<songTitles.size();i++){
SearchResult searchResult = new SearchResult();
Elements urls = songTitles.get(i).getElementsByTag("img");
searchResult.setFoodName(urls.get(0).attr("alt")); // 食物名称 1
searchResult.setFoodPic(urls.get(0).attr("src")); // 食物图片 2
Elements urls2 = songTitles.get(i).getElementsByTag("a");
searchResult.setFoodUrl(Constant.BOHE_HOME_PAGE + urls2.get(0).attr("href")); // 食物连接 3
//searchResult.setFoodKa(songTitles.get(i).getElementsByTag("p").toString()); // 卡路里 4
// kaluli_pp 带2个p标签 kaluli_p 带1个p标签 kaluli 带0个p标签
String kaluli_pp = songTitles.get(i).getElementsByTag("p").toString(); // <p>热量:77 大卡(每100克)</p>
String kaluli_p = kaluli_pp.replace("<p>", ""); // 替换掉<p>
String kaluli = kaluli_p.replace("</p>", ""); // 替换掉</p>
searchResult.setFoodKa(kaluli); // 卡路里 4
System.out.println("MainActivity@searchResult : " + searchResult);
searchResults.add(searchResult);//把最终的所有信息,添加到集合
}
System.out.println("MainActivity@searchResults : " + searchResults);
//System.out.println("@songTitles.size() : " + searchResults.size());
} catch (IOException e) {
e.printStackTrace();
return -1;
}
return 1;
}
// onPostExecute方法用于在执行完后台任务后更新UI,显示结果
@Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
if (result==1){
asyncResponse.onDataReceivedSuccess(searchResults);// 将结果传给回调接口中的函数
}else {
asyncResponse.onDataReceivedFailed();
}
}
}AsyncResponse.java:
package com.iwanghang.booheesearchdemo;
import java.util.ArrayList;
public interface AsyncResponse {
void onDataReceivedSuccess(ArrayList<SearchResult> searchResults);
void onDataReceivedFailed();
}activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.iwanghang.booheesearchdemo.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="食物卡路里一期Demo by iwanghang" />
<ListView
android:id="@+id/listView_food"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:cacheColorHint="@android:color/transparent"
android:listSelector="@android:color/transparent"
android:overScrollMode="never"
android:scrollbars="none"
android:visibility="visible"/>
</LinearLayout>
item_food_list.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">
<ImageView
android:id="@+id/iv_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/food_32px"
android:layout_marginRight="10dp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginRight="10dp"
android:orientation="vertical">
<TextView
android:id="@+id/tv_foodName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:text="tv_foodName" />
<TextView
android:id="@+id/tv_kaLuli"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#a6a8a8"
android:text="tv_kaLuli"/>
</LinearLayout>
<ImageView
android:id="@+id/iv_details"
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@drawable/local_food_more"/>
</LinearLayout>
项目下载:http://download.csdn.net/detail/iwanghang/9828141
转载请注明出处:http://blog.csdn.net/iwanghang/article/details/70882420
欢迎移动开发爱好者交流
沈阳或周边城市公司有意开发Android,请与我联系
联系方式
微信:iwanghang
QQ:413711276
邮箱:iwanghang@qq.com
觉得博文有用,请点赞,请评论,请关注,谢谢!~
相关文章推荐
- Android开发-魔窗DeeplinkDemo-AndroidStudio
- Android开发-TextViewDemo-AndroidStudio
- Android开发-DesignDemo-AndroidStudio(十一)FloatingActionButton(3)
- Android开发-DesignDemo-AndroidStudio(十二)TextInputLayout
- Android开发-登录界面Demo-AndroidStudio
- Android开发-DesignDemo-AndroidStudio(五)Coordinator
- Android开发-DesignDemo-AndroidStudio(十二)TextInputLayout
- Android开发-DesignDemo-AndroidStudio(三)右滑菜单点击监听
- Android开发-DesignDemo-AndroidStudio(四)单选、子菜单、header
- Android开发-DesignDemo-AndroidStudio(一)ViewPager实现
- Android开发-ImageViewDemo-AndroidStudio
- Android开发-DesignDemo-AndroidStudio(九)FloatingActionButton(1)
- Android开发-DesignDemo-AndroidStudio(三)右滑菜单点击监听
- Android开发-SQLiteDemo增删改查-AndroidStudio-项目应用-里程记录
- Android开发-SQLiteDemo增删改查-AndroidStudio
- Android开发-Volley-解析Json使用方法-完整Demo-AndroidStudio
- Android开发-DesignDemo-AndroidStudio(八)CoordinatorDemo(3)
- Android开发 用AndroidStudio开发百度地图Demo时的经典错误230的另一种可能
- Android开发-DesignDemo-AndroidStudio(九)FloatingActionButton(1)
- Android开发-DesignDemo-AndroidStudio(四)单选、子菜单、header