ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

从零开始用Andrid Studio开发一个简单的垃圾分类查询APP(4) —完结篇

2020-12-08 19:33:21  阅读:248  来源: 互联网

标签:完结篇 search String garbage Andrid private Studio new id


已经是写这个小APP的第四天了,今天我们继续看看能实现到什么程度。

(续)1.搜索结果页面布局

上个帖子中我们已经决定了就用ListView进行布局,接下来就是我们美化定制这个ListView了。
关于定制ListView,我们尝试跟着课本走一次:
新建一个garbages文件夹,用于放我们的“垃圾”,然后在其中新建一个Garbage_list类,用于作为ListView的适配器的适配类型。
我们在第二个帖子里已经决定了,在这个选项里面放的是“名字”和“分类”,代码如下:

public class Garbage_list {
    private JSONObject search_result= MainActivity.Search_JSON;
    private String name;
    private int garbage_type;           //0是可回收,1是有害垃圾,2是厨余垃圾,3是干垃圾(其它垃圾)
    private String[] garbage_type_string={"可回收垃圾","有害垃圾","厨余垃圾","其它垃圾(干垃圾)"};

    public Garbage_list(JSONObject the_garbage_JSON) throws JSONException {
        name=the_garbage_JSON.getString("name");
        garbage_type=Integer.parseInt(the_garbage_JSON.getString("type"));
    }
    
    public String getName(){
        return name;
    }
    
    public String getType(){
        return garbage_type_string[garbage_type];
    }
}

这里的代码随便写写,很简单的,大家应该都看得懂,其中只涉及到一个字符串转数字。

接下来我们为选项指定一个自定义布局,同样,在layout目录下新建一个garbage_item.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="wrap_content">

    <TextView
        android:id="@+id/garbage_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"/>

    <TextView
        android:id="@+id/garbage_type"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"/>
    
</LinearLayout>

我们写了两个TextView,且都设置为竖直居中。

然后我们创建一个自定义适配器,将泛型指定为Garbage_list类,(泛型是甚么东西?不知道,推荐不知道的朋友们百度一下,我也不细说了。)
我们在垃圾文件夹中新建一个类Garbage_adapter,代码如下:

public class Garbage_adapter extends ArrayAdapter {
    private int resourceId;
    
    public Garbage_adapter(Context context, int textViewResourceId, List<Garbage_list> objects){
        super(context,textViewResourceId,objects);
        resourceId=textViewResourceId;
    }
    
    @Override
    public View getView(int position, View convertView, ViewGroup parent){
        Garbage_list garbage_list= (Garbage_list) getItem(position);
        View view= LayoutInflater.from(getContext()).inflate(resourceId, parent,false);
        TextView garbageName=(TextView)view.findViewById(R.id.garbage_name);
        TextView garbageType=(TextView)view.findViewById(R.id.garbage_type);
        garbageName.setText(garbage_list.getName());
        garbageType.setText(garbage_list.getType());
        return view;
    }
}

这里我也不太懂,大概就是把之前的类实时传给布局文件的意思吧。
接下来我们为SearchActivity中修改代码:

public class SearchActivity extends AppCompatActivity {
    private JSONObject search_result=MainActivity.Search_JSON;      //用于接收MainActivity中的搜索结果
    private List<Garbage_list> garbageList=new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search);
        ActionBar actionbar=getSupportActionBar();
        if(actionbar!=null){
            actionbar.hide();
        }

        try {
            init_garbage_list();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        Garbage_adapter adapter=new Garbage_adapter(SearchActivity.this, R.layout.garbage_list, garbageList);
        ListView listView=(ListView)findViewById(R.id.search_listview);
        listView.setAdapter(adapter);


    }

    private JSONObject make_the_JSON(int i) throws JSONException {            //用于将JSON转换为字符串数组
        JSONArray newslist=search_result.getJSONArray("newslist");
        String[] name=new String[newslist.length()];
        String newslistString=new String();
        JSONObject the_garbage_JSON=new JSONObject();       //具体某一项的json ,可以通过getstring获得其中具体的项
        newslistString=newslist.getString(i);
        the_garbage_JSON=new JSONObject(newslistString);
//        name[i]=the_garbage_JSON.getString("name");
        return the_garbage_JSON;
    }


    private void init_garbage_list() throws JSONException {
        JSONArray newslist=search_result.getJSONArray("newslist");
        for(int i=0;i<newslist.length();i++){
            Garbage_list the_garbage=new Garbage_list(make_the_JSON(i));
            garbageList.add(the_garbage);
        }
    }
}

运行一下:

好家伙,够接地气,书上的部分就结束了,因为书上是图片加文字,所以什么都不设置都能看,我们这个就不行了。
这里楼主首先试了试把garbage_list.xml改成RelativeLayout,结果发现页面切换不过去了,可能是因为我们现在的适配器没法适配这个的原因吧,所以我们只能回来继续用LinearLayout继续调试了,经过楼主的不断改动,终于是可以看了:如图:

代码如下:

<?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="wrap_content">

    <TextView
        android:id="@+id/garbage_name"
        android:layout_width="245dp"
        android:layout_height="60dp"
        android:layout_alignParentTop="true"
        android:layout_gravity="center_vertical"
        android:layout_marginTop="0dp"
        android:gravity="center_vertical"
        android:textAppearance="@style/TextAppearance.AppCompat.Large"
        android:textSize="20dp" />

    <TextView
        android:id="@+id/garbage_type"
        android:layout_width="165dp"
        android:layout_height="60dp"
        android:layout_alignParentTop="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_gravity="center_vertical"
        android:layout_marginTop="0dp"
        android:layout_marginEnd="-6dp"
        android:layout_marginRight="-6dp"
        android:gravity="center"
        android:textAppearance="@style/TextAppearance.AppCompat.Medium" />

</LinearLayout

接下来我们依次为搜索页面的控件添加事件,首先是上面的搜索组合:
先声明一下控件和url:

	private EditText text_search_garbage;
    private Button btn_search_garbage;
        String url_garbage="https://api.tianapi.com/txapi/lajifenlei/index?key=xxxxxxxxxxxxxxxxxxxxxxxxxx&word=";

然后复制MainActivity中的相应部分过来改一下,基本上把MainActivity改成SearchActivity就可以了,然后加个结束页面,代码如下:

    private void init_search(){
        View view = getWindow().peekDecorView();
        if (view != null) {//这里是网络访问的代码,获取服务
            InputMethodManager inputmanger = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            inputmanger.hideSoftInputFromWindow(view.getWindowToken(), 0);
        }
        initData_search();
    }

    Handler handler_search=new Handler(new Handler.Callback() {//首先通过handler发送信息
        @Override
        public boolean handleMessage(@NonNull Message msg) {
            switch (msg.what){
                case 0:
                    Toast.makeText(SearchActivity.this,"网络错误",Toast.LENGTH_LONG).show();
                    break;
                case 1:
                    String json=(String)msg.obj;
                    try{
                        MainActivity.Search_JSON=new JSONObject(json);
                        Intent intent=new Intent();
                        intent.setClass(SearchActivity.this, SearchActivity.class);
                        startActivity(intent);
                        finish();               //结束掉现在的页面,直接返回主页。(假装可以刷新)
                        break;
                    }catch (JSONException e){
                        e.printStackTrace();
                    }
                default:
                    throw new IllegalStateException("Unexpected value: " + msg.what);
            }
            return false;
        }
    });

    private void initData_search(){                 //接着用这个方法调用handler,并把返回的信息放入TextView
//        handler_beauty.sendEmptyMessage(1);
        String data=text_search_garbage.getText().toString();
        if(TextUtils.isEmpty(data)){//如果内容为空,弹出toast消息,不为空则执行164行以后的代码
            Toast.makeText(SearchActivity.this,"垃圾名称不能为空!",Toast.LENGTH_SHORT).show();
        }
        else{
            Okhttp_work.OkHttpGet(url_garbage+data, new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    String content=response.body().string();
                    Message message=new Message();
                    message.what=1;
                    message.obj=content;
                    handler_search.sendMessageDelayed(message,10);
                }
            });
        }
    }

最后在onCreate中加入定义和监听器就完成了:

        text_search_garbage=findViewById(R.id.search_edit_text);
        btn_search_garbage=findViewById(R.id.button_search);

        try {
            init_garbage_list();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        Garbage_adapter adapter=new Garbage_adapter(SearchActivity.this, R.layout.garbage_list, garbageList);
        ListView listView=(ListView)findViewById(R.id.search_listview);
        listView.setAdapter(adapter);

        btn_search_garbage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                init_search();
            }
        });

测试一下是成功的,这里我就不截图了。

接下来是为ListView添加点击事件,让我们能够进入详情页面:
这一段书上又没有介绍了,所以又需要我们操起老本行了,
这里楼主要感谢百度知道 Android开发 关于ListView的点击事件 中的第一个答案,让楼主成功达成了点击事件。
我们依旧是先在SearchActivity中声明两个变量:

    private ListView garbageList_View;
    public int garbage_id;

然后写ListView的点击事件:

garbageList_View=findViewById(R.id.search_listview);
        garbageList_View.setOnItemClickListener(new AdapterView.OnItemClickListener(){
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                garbage_id=i;
                Intent intent=new Intent();
                intent.setClass(SearchActivity.this, DetailActivity.class);
                startActivity(intent);
            }
        });

这样我们在打开新页面的同时,也把点击的选项id放入了全局变量garbage_id中,这样下个页面就可以直接调用这个参数了。

OK!搜索结果页面完成!(有木有想大吼一声啊~)

2.进入详情页面

做到这里,楼主发现一个大问题,我们没有图片,所以这波进入详情之后会是很生硬的文字堆叠,很丑,如果这波有图片,那我们这将会是绝杀,可惜有不得。
有不得的话,那自然是上来一堆TextView,一堆setText,就完事了,虽说这样有点太简单了,不过没关系,我们后面再画个一两个小时专门美化一下就好了。
现在先来实现吧:
先新建一个normal_detail.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="60dp"
    android:background="@drawable/title_bg">

</RelativeLayout>

作为空白的导航栏,然后修改activity_detail.xml代码如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".DetailActivity">

    <include
        android:id="@+id/include_detail_title"
        layout="@layout/normal_title"
        app:layout_constraintBottom_toTopOf="@+id/main_image" />

    <TextView
        android:id="@+id/detail_garbage_name"
        android:layout_width="266dp"
        android:layout_height="69dp"
        android:layout_below="@+id/include_detail_title"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:layout_marginStart="0dp"
        android:layout_marginLeft="0dp"
        android:layout_marginTop="3dp"
        android:text="暂时没有网络连接~" />

    <TextView
        android:id="@+id/detail_garbage_type"
        android:layout_width="146dp"
        android:layout_height="69dp"
        android:layout_below="@+id/include_detail_title"
        android:layout_marginStart="0dp"
        android:layout_marginLeft="0dp"
        android:layout_marginTop="3dp"
        android:layout_toEndOf="@+id/detail_garbage_name"
        android:layout_toRightOf="@+id/detail_garbage_name"
        android:text="暂时没有网络连接~" />

    <TextView
        android:id="@+id/detail_garbage_explain"
        android:layout_width="match_parent"
        android:layout_height="135dp"
        android:layout_below="@+id/include_detail_title"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:layout_marginStart="0dp"
        android:layout_marginLeft="0dp"
        android:layout_marginTop="74dp"
        android:text="暂时没有网络连接~" />

    <TextView
        android:id="@+id/detail_garbage_contain"
        android:layout_width="match_parent"
        android:layout_height="122dp"
        android:layout_below="@+id/include_detail_title"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:layout_marginStart="0dp"
        android:layout_marginLeft="0dp"
        android:layout_marginTop="210dp"
        android:text="暂时没有网络连接~" />

    <TextView
        android:id="@+id/detail_garbage_tips"
        android:layout_width="match_parent"
        android:layout_height="78dp"
        android:layout_below="@+id/include_detail_title"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_marginTop="332dp"
        android:layout_marginEnd="0dp"
        android:layout_marginRight="0dp"
        android:text="暂时没有网络连接~" />

</RelativeLayout>

看着多,其实就是随便拖了五个TextView,字体什么的我们先不管,随便放一下,后面再改。最后修改DetailActivity代码如下:

public class DetailActivity extends AppCompatActivity {
    private TextView garbage_name;
    private TextView garbage_type;
    private TextView garbage_explain;
    private TextView garbage_contain;
    private TextView garbage_tips;
    private JSONObject search_result=MainActivity.Search_JSON;
    private int detail_garbage_id=SearchActivity.garbage_id;
    private String[] garbage_type_string={"可回收垃圾","有害垃圾","厨余垃圾","其它垃圾(干垃圾)"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_detail);
        ActionBar actionbar=getSupportActionBar();
        if(actionbar!=null){
            actionbar.hide();
        }

        garbage_name=findViewById(R.id.detail_garbage_name);
        garbage_type=findViewById(R.id.detail_garbage_type);
        garbage_explain=findViewById(R.id.detail_garbage_explain);
        garbage_contain=findViewById(R.id.detail_garbage_contain);
        garbage_tips=findViewById(R.id.detail_garbage_tips);


        try {
            garbage_name.setText(make_the_String("name"));
        } catch (JSONException e) {
            e.printStackTrace();
        }
        try {
            garbage_type.setText(garbage_type_string[Integer.parseInt(make_the_String("type"))]);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        try {
            garbage_explain.setText(make_the_String("explain"));
        } catch (JSONException e) {
            e.printStackTrace();
        }
        try {
            garbage_contain.setText(make_the_String("contain"));
        } catch (JSONException e) {
            e.printStackTrace();
        }
        try {
            garbage_tips.setText(make_the_String("tip"));
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }


    private String make_the_String(String need) throws JSONException {            //用于将JSON转换为字符串数组
        JSONArray newslist=search_result.getJSONArray("newslist");
//        String[] name=new String[newslist.length()];
        String newslistString=new String();
        JSONObject the_garbage_JSON=new JSONObject();       //具体某一项的json ,可以通过getstring获得其中具体的项
        newslistString=newslist.getString(detail_garbage_id);
        the_garbage_JSON=new JSONObject(newslistString);
//        name[i]=the_garbage_JSON.getString("name");
        return the_garbage_JSON.getString(need);
    }
}

相信对于一直看到这里的朋友们这个已经很简单了,我也就不细说了,其实就是用之前编写的方法工具复制过来用罢了。测试一下:

成功显示,没有bug。

接下来就到我们的三岔路口了,我们是该开始着手美化APP呢,还是继续研究添加数据库的功能呢?
楼主想了想,还是算了吧,头已经在发热了,急需一个水冷来降温了,就不做什么数据库了,从刚开始接触数据库一直到现在,楼主真的一听到数据库就头大,什么连接什么的,当时用python连接数据库差点没把我送走。
所以我的下一步就是轻松愉快的美化APP啦!(“我要补充”,删~;“EditActivity”,删。)

美化的步骤我就不放在这里啦,毕竟也没剩多少技术含量了。

大家如果有兴趣可以用我博客里的代码自己操作一番,源码都在博客里面附着,所以楼主就不单独给大家打包源码了,毕竟楼主也是为了自己完成作业嘛,哈哈^ _ ^。

完结

(ps:楼主以后也会不断更新更多有意思的小知识的,所以就点一下辣个大拇指和关注吧,它们会亮的哇!QωQ)

最后附上楼主美化完的截图(加了几个无伤大雅的简单页面):


另外主页的按钮点进去是相应的介绍,“了解更多”按钮是打开百度网页(/捂脸)。是不是感觉好多了QwQ

标签:完结篇,search,String,garbage,Andrid,private,Studio,new,id
来源: https://blog.csdn.net/qq_44178379/article/details/110589712

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有