上一篇我们说到关于服务的编写(以绑定非绑定音乐播放为例),此次记录,实现的是线程的异步,即使用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