【移动开发技术——安卓(part4)】:AsyncTask实现异步任务及RecycleView的点击事件

上一篇参见:
(18条消息) 移动开发技术【安卓part3】——实现绑定/非绑定音乐播放服务及系统广播式启动音乐服务_With_Zero的博客-CSDN博客https://blog.csdn.net/m0_61067829/article/details/124280018

上一篇我们说到关于服务的编写(以绑定非绑定音乐播放为例),此次记录,实现的是线程的异步,即使用android中的AsyncTask,它会自动创建线程而不同于java中需要使用Thread写方法再启动。顺便我们对于界面的设计有所更新也顺便一提。同时本篇也会提到如何实现RecycleView实现点击事件。

一、整体设计更新说明

(异步控制请直接参见第二部分)

【首先】先看一下我们的目录结构

 1、界面更新说明

(1)微信界面

        微信界面这里使用RecycleListView控件,如下图可见,主要展示的文字内容,在微信Frament对应代码控制传入。这里不多解释,之前有关于此控件的介绍(后面也用到RecycleView,有新的实现)。

(2)联系人界面

和微信界面相同处理,不做说明。

(3)朋友圈

上一篇也有展示,不做说明。

(4)设置界面

        设置界面,此界面只是一个静态界面,没有做一些控件的实现,本次的任务,也都分装在此界面的服务Layout中

        点击服务后,会有页面的跳转,跳转是从Fragment跳转到Activity,在这个页面中,同样使用RecycleView,然后通过点击RecycleView中对应的Item,实现对应的功能。

 (5)关于RecycleView中的点击事件实现

        当我们在使用到RecycleView后,我们如何使用点击事件呢?我们会发现,没法对任意一个item进行直接定位点击(像button那样)。根据代码,我们来进行说明。

 【代码说明】

        针对此时这个页面的代码,我们知道它是一个Activity,然后链接页面,对于RecycleView的写法,在此展示:

(Baidu_Map.java)Activity

        //对recycleview进行配置
        recyclerView = (RecyclerView) this.findViewById(R.id.recyclerView_Baidu_Map);

        //数据
        String [] people = {"百度定位","MyAsyncTask","待开发..."};
        String [] message = {"","","后续即将上线"};

        Context context = this;

        List<Map<String,Object>> data = new ArrayList<>();
        for (int i = 0 ; i <people.length;i++)
        {
            Map<String,Object> itemdata = new HashMap<>();

            itemdata.put("key1",people[i]);
            itemdata.put("key2",message[i]);

            data.add(itemdata);
        }

        myadpter_baiduMap = new Myadpter_BaiduMap(context,data);

        LinearLayoutManager manager = new LinearLayoutManager(context);

        manager.setOrientation(RecyclerView.VERTICAL);

        recyclerView.setLayoutManager(manager);

        //分割线
        DividerItemDecoration mDivider = new DividerItemDecoration(context, DividerItemDecoration.VERTICAL);
        recyclerView.addItemDecoration(mDivider);


        recyclerView.setAdapter(myadpter_baiduMap);

        因为此时是在Activity中书写,而不同于Fragment,在Fragment中我们可能需要定义View,然后通过更改在把这个View返回return,但是在Activity中并不需要,Fragment就是依赖于Activity的。

        其中,我们会使用到Myadpter_BaiduMap,是我们自己改写继承了RecycleView.Adapter的一个适配器法。

【Myadpter_BaiduMap】

public class Myadpter_BaiduMap extends RecyclerView.Adapter<Myadpter_BaiduMap.MyviewHolder> {


    private List<Map<String,Object>> data;
    private Context context;
    private MyItemClickListener myItemClickListener;
//    private LayoutInflater layoutInflater;



    public Myadpter_BaiduMap(Context context, List<Map<String,Object>> data) {
        this.context = context;
        this.data = data;

    }

    @NonNull
    @Override
    //就相当于指针,ViewHolder是抽象的,所以需要创建其子类返回
    public MyviewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        //视图压缩
        View view = LayoutInflater.from(context).inflate(R.layout.item_list_baidumap,parent,false);
        MyviewHolder holder = new MyviewHolder(view,myItemClickListener);
        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull MyviewHolder holder, int position) {
        holder.baidumap_text1.setText(data.get(position).get("key1").toString());
        holder.baidumap_text2.setText(data.get(position).get("key2").toString());
        holder.itemView.setTag(data.get(position));


    }

    @Override
    public int getItemCount() {
        return data.size();
    }


    public void setOnItemClickListener(MyItemClickListener myItemClickListener)
    {
        this.myItemClickListener = myItemClickListener;
    }


    public class MyviewHolder extends RecyclerView.ViewHolder {
        TextView baidumap_text1,baidumap_text2;
        private MyItemClickListener myItemClickListener;

        public MyviewHolder(@NonNull View itemView,MyItemClickListener myItemClickListener) {
            super(itemView);
            baidumap_text1 = itemView.findViewById(R.id.baidumap_text1);
            baidumap_text2 = itemView.findViewById(R.id.baidumap_text2);

            this.myItemClickListener = myItemClickListener;

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (myItemClickListener!=null) {
//                        if (getPosition()==0) {
//                            myItemClickListener.onItemClick1(view, 0);
//                        }
                        switch(getPosition())
                        {
                            case 0 :
                                myItemClickListener.onItemClick1(view, 0);break;
                            case 1 :
                                myItemClickListener.onItemClick2(view, 1);break;
                            case 2 :
                                myItemClickListener.onItemClick3(view, 2);break;
                            default: break;
                        }
                    }
                }
            });
        }
    }
}


interface MyItemClickListener{
    public void onItemClick1(View view,int postion);
    public void onItemClick2(View view,int postion);
    public void onItemClick3(View view,int postion);

}

        此时,RecycleView就基本实现了。但是我们重点不是介绍这里,而是要去说明点击事件。在上面的适配器中,我们看到我们写了一个MyviewHolder类,这个类是在onBindViewHolder中所需要,而这个holder就相当于一个句柄,也可以类似理解为指针,从而给对应item下的文字(题目)进行赋值。(注意加上:holder.itemView.setTag(data.get(position));

         在下面这个部分中,我们定义了点击事件,在我们点击RecycleView中的某一行时,都会对应有一个position,因此我们根据它的position来判断,是对哪一行进行了点击。

         但是我们发现,我们还是用了一个myItemClickListener的东西,这是我们自己定义的监听接口,g根据点击不同,调用对应不同方法。

         既然是个接口,那么具体方法怎么实现呢?回到刚才的Activity,这里就进行了实现,因为我们可以看到myadpter_baiduMap只能定义一个监听,它中间的参数传递new MyItemClickListener(),那么就好办了,直接覆盖重写对应方法即可,由此就可以实现了。【此方法不知道是否通用或者是否有太多bug,是本人自行摸索写出,没有太多参考资料,特此说明】

(Baidu_Map.java)Activity

  Intent intent1 = new Intent(this,BaiduMap_OpenUse.class);
        Intent intent3 = new Intent(this,MyAsyncTaskActivity.class);
        Intent intent4 = new Intent(this,TextActivity.class);

        myadpter_baiduMap.setOnItemClickListener(new MyItemClickListener() {
            @Override
            public void onItemClick1(View view, int postion) {

                startActivityForResult(intent1,2);
            }
            @Override
            public void onItemClick2(View view, int postion) {
                startActivityForResult(intent3,3);
            }
            @Override
            public void onItemClick3(View view, int postion) {
                startActivityForResult(intent4,4);
            }
        });

Baidu_Map.java完整代码(Myadpter_BaiduMap上面已经是完整的了


public class Baidu_Map extends AppCompatActivity {

    private RecyclerView recyclerView;
    private Myadpter_BaiduMap myadpter_baiduMap;
    private View view;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);//隐藏项目名
        setContentView(R.layout.activity_baidu_map);

        Intent intent2 = getIntent();

//        Bundle bundle=intent2.getExtras();
//        String Str1 = bundle.get("name").toString();
//        String Str2 = bundle.get("class").toString();

        intent2.putExtra("result","result:ok");
        setResult(1,intent2);


        //对recycleview进行配置
        recyclerView = (RecyclerView) this.findViewById(R.id.recyclerView_Baidu_Map);

        //数据
        String [] people = {"百度定位","MyAsyncTask","待开发..."};
        String [] message = {"","","后续即将上线"};

        Context context = this;

        List<Map<String,Object>> data = new ArrayList<>();
        for (int i = 0 ; i <people.length;i++)
        {
            Map<String,Object> itemdata = new HashMap<>();

            itemdata.put("key1",people[i]);
            itemdata.put("key2",message[i]);

            data.add(itemdata);
        }

        myadpter_baiduMap = new Myadpter_BaiduMap(context,data);

        LinearLayoutManager manager = new LinearLayoutManager(context);

        manager.setOrientation(RecyclerView.VERTICAL);

        recyclerView.setLayoutManager(manager);

        //分割线
        DividerItemDecoration mDivider = new DividerItemDecoration(context, DividerItemDecoration.VERTICAL);
        recyclerView.addItemDecoration(mDivider);


        recyclerView.setAdapter(myadpter_baiduMap);

        
        

        Intent intent1 = new Intent(this,BaiduMap_OpenUse.class);
        Intent intent3 = new Intent(this,MyAsyncTaskActivity.class);
        Intent intent4 = new Intent(this,TextActivity.class);

        myadpter_baiduMap.setOnItemClickListener(new MyItemClickListener() {
            @Override
            public void onItemClick1(View view, int postion) {

                startActivityForResult(intent1,2);
            }
            @Override
            public void onItemClick2(View view, int postion) {
                startActivityForResult(intent3,3);
            }
            @Override
            public void onItemClick3(View view, int postion) {
                startActivityForResult(intent4,4);
            }
        });

    }
}

二、AsyncTask实现异步任务

1.实现效果说明

        如下图所示,我们主要模拟的是后台下载的一个效果展示,同时使用网络连接,这里我们访问某度的主页,然后将其主页面进行拉取下载。当然,从网络下载对应页面是很快的,但是这里是一种效果展示,因此会在进度加载完成后展示,此处解释一下。

 2、代码实现

(1)MyAsyncTaskActivity

这里都是对控件的绑定及点击事件。

public class MyAsyncTaskActivity extends AppCompatActivity {

    public static Button button;
    public static ProgressBar progressBar;
    public static ImageView imageView;
    public static TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);//隐藏项目名
        setContentView(R.layout.activity_my_async_task);

        button = findViewById(R.id.button_myasynctask);
        progressBar = findViewById(R.id.progressBar_myasynctask);
        imageView = findViewById(R.id.imageView_myasynctask);
        textView = findViewById(R.id.textView_myasynctask);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new MyAsyncTask().execute();
            }
        });
    }
}

(2)MyAsyncTask

这里是一个异步任务,AsyncTask会自动创建线程操作从而异步执行。其中这里实现了点击事件后的进度条操作,同时还进行了网络连接。

public class MyAsyncTask extends AsyncTask<String,Integer,String> {

    @Override
    protected void onPreExecute() {

        MyAsyncTaskActivity.progressBar.setVisibility(View.VISIBLE);
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(String... strings) {
        String httpUrl = "https://www.baidu.com";
        String resultData = "";
        URL url = null;
        int step = 1;

        try {
          url = new URL(httpUrl);

            while (step <= 100) {
                publishProgress(step++);//step的值传递给onProgressUpdate(Integer... values)中的values参数
                Thread.sleep(50);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
            Log.d("TAG","URL对象创建失败!");
        }

        if (url != null )
        {
            try {
                HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                //服务器返回数据字符流,网页文档编码一般为UTF-8
                InputStreamReader in = new InputStreamReader(urlConnection.getInputStream(),Charset.defaultCharset());
                //为输出创建BufferedRead
                BufferedReader bufferedReader = new BufferedReader(in);
                String inputLine = null;
                while ((inputLine = bufferedReader.readLine())!=null)
                {
                    resultData += inputLine+"\n";
                }
                in.close();
                urlConnection.disconnect();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultData;
    }

    @Override
    protected void onPostExecute(String resultData) {
        if (resultData!=null)
        {
            MyAsyncTaskActivity.textView.setText(resultData);
        }else {
            MyAsyncTaskActivity.textView.setText("Sorry,the content is null");
        }
        MyAsyncTaskActivity.progressBar.setVisibility(View.GONE);   //移除ProgressBar
        MyAsyncTaskActivity.button.setText("DownLoad is done."); //异步任务返回的数据更新UI
        super.onPostExecute(resultData);
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        MyAsyncTaskActivity.progressBar.setProgress(values[0]); //更新ProgressBar
        super.onProgressUpdate(values);
        MyAsyncTaskActivity.button.setText("后台正在下载...");

    }
}

总结

        到此我们今天的内容就讲述完毕了,主要包括为:进度状态更新、RecycleView点击事件、AsyncTask实现异步任务。

本篇gitee:https://gitee.com/with-zero/android_-studion_-mobile.git

With_Zero  2022.05.27

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值