Android仿微信选择图片
效果展示

首先先添加用到的权限
<uses-permission android:name="android.permission.INTERNET" /><!--获取手机存储卡权限--><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
6.0之后动态获取权限
//6.0之后要动态获取权限,重要!!!protected void judgePermission() {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {// 检查该权限是否已经获取// 权限是否已经 授权 GRANTED---授权 DINIED---拒绝// sd卡权限String[] SdCardPermission = {Manifest.permission.WRITE_EXTERNAL_STORAGE};if (ContextCompat.checkSelfPermission(this, SdCardPermission[0]) != PackageManager.PERMISSION_GRANTED) {// 如果没有授予该权限,就去提示用户请求ActivityCompat.requestPermissions(this, SdCardPermission, 100);}//手机状态权限String[] readPhoneStatePermission = {Manifest.permission.READ_PHONE_STATE};if (ContextCompat.checkSelfPermission(this, readPhoneStatePermission[0]) != PackageManager.PERMISSION_GRANTED) {// 如果没有授予该权限,就去提示用户请求ActivityCompat.requestPermissions(this, readPhoneStatePermission, 200);}//定位权限String[] locationPermission = {Manifest.permission.ACCESS_FINE_LOCATION};if (ContextCompat.checkSelfPermission(this, locationPermission[0]) != PackageManager.PERMISSION_GRANTED) {// 如果没有授予该权限,就去提示用户请求ActivityCompat.requestPermissions(this, locationPermission, 300);}String[] ACCESS_COARSE_LOCATION = {Manifest.permission.ACCESS_COARSE_LOCATION};if (ContextCompat.checkSelfPermission(this, ACCESS_COARSE_LOCATION[0]) != PackageManager.PERMISSION_GRANTED) {// 如果没有授予该权限,就去提示用户请求ActivityCompat.requestPermissions(this, ACCESS_COARSE_LOCATION, 400);}String[] READ_EXTERNAL_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE};if (ContextCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE[0]) != PackageManager.PERMISSION_GRANTED) {// 如果没有授予该权限,就去提示用户请求ActivityCompat.requestPermissions(this, READ_EXTERNAL_STORAGE, 500);}String[] WRITE_EXTERNAL_STORAGE = {Manifest.permission.WRITE_EXTERNAL_STORAGE};if (ContextCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE[0]) != PackageManager.PERMISSION_GRANTED) {// 如果没有授予该权限,就去提示用户请求ActivityCompat.requestPermissions(this, WRITE_EXTERNAL_STORAGE, 600);}}}
加载图片和查看图片分别用到 glide和 BigImageViewer
添加依赖
implementation 'com.github.bumptech.glide:glide:4.9.0'annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'implementation 'com.github.piasy:BigImageViewer:1.5.7'
在settings.gradle添加 maven { url 'https://www.jitpack.io' }
dependencyResolutionManagement {repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)repositories {google()mavenCentral()maven { url 'https://www.jitpack.io' }}
}
实现代码
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"android:orientation="vertical"tools:context=".MainActivity"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:background="#000"android:orientation="horizontal"><ImageViewandroid:id="@+id/iv_back"android:clickable="true"android:src="@drawable/back_round"android:layout_width="45dp"android:layout_height="45dp" /><TextViewandroid:textColor="#fff"android:gravity="center"android:text="@string/choose_image"android:layout_width="0dp"android:layout_weight="1"android:layout_height="match_parent" /><TextViewandroid:id="@+id/tv_confirm"android:clickable="true"android:text="@string/complete"android:background="@drawable/bg_item_type"android:textColor="#888"android:gravity="center"android:paddingLeft="10dp"android:paddingRight="10dp"android:layout_margin="5dp"android:layout_width="wrap_content"android:layout_height="35dp" /></LinearLayout><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/r_layout"android:layout_gravity="center_horizontal"android:layout_width="wrap_content"android:layout_height="match_parent" /></LinearLayout>
item.xml 显示图片
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="#999"android:padding="0.8dp"><ImageViewandroid:id="@+id/imageView2"android:padding="1dp"android:background="#000000"android:layout_width="match_parent"android:layout_height="wrap_content"android:clickable="true"android:scaleType="centerCrop" /><LinearLayoutandroid:id="@+id/ll_check"android:padding="10dp"android:clickable="true"android:layout_alignParentRight="true"android:layout_gravity="right"android:layout_width="40dp"android:layout_height="40dp"android:gravity="center"android:orientation="vertical"><TextViewandroid:id="@+id/tv_check"android:src="@drawable/radio_unchecked"android:textColor="#fff"android:gravity="center"android:layout_width="match_parent"android:layout_height="match_parent" /></LinearLayout></FrameLayout>
MainActivity.java
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;import android.icu.text.SimpleDateFormat;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;import java.io.File;
import java.net.Socket;
import java.text.ParsePosition;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;public class MainActivity extends AppCompatActivity {static final int ACTION_TO_CAMERA = 1;static final int ACTION_TO_CUT = 2;static final int ACTION_TO_PREVIEW = 3;private RecyclerView rv;private MyAdapter adapter;private List<Photo> mPhotoList= new ArrayList<Photo>();@RequiresApi(api = Build.VERSION_CODES.N)@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//去掉顶部标题getSupportActionBar().hide();setContentView(R.layout.activity_main);rv = (RecyclerView) findViewById(R.id.r_layout);adapter = new MyAdapter(MainActivity.this);judgePermission(); //获取权限initData(); //获取图片// 向适配器set数据GridLayoutManager gridLayoutManager = new GridLayoutManager(getApplicationContext(), 4,LinearLayoutManager.VERTICAL,false);adapter.setData(mPhotoList);rv.setLayoutManager(gridLayoutManager);rv.setAdapter(adapter);}@RequiresApi(api = Build.VERSION_CODES.N)private void initData() {//读取手机中的相片Cursor cursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, null);if(mPhotoList != null){mPhotoList = null;mPhotoList= new ArrayList<Photo>();}while (cursor.moveToNext()) {//获取图片的路径String path=cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));if(path!=null && path.length() >0) {//获取图片的名称String name = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME));//获取图片最后修改的日期File file = new File(path);long modifieTime = file.lastModified();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");String date = sdf.format(new Date(modifieTime));//获取图片的大小long size = cursor.getLong(cursor.getColumnIndex(MediaStore.Images.Media.SIZE));Photo photo = new Photo(name, date, size, path);mPhotoList.add(photo);}}mPhotoList = sortList(mPhotoList);System.out.println("个数:"+mPhotoList.size());}/*** List按照时间降序排列* @param L* @return*/@RequiresApi(api = Build.VERSION_CODES.N)private List<Photo> sortList(List<Photo> L){SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");Photo temp = new Photo();//冒泡排序,大的时间在数组的前列for(int i=0; i<L.size()-1; i++){for(int j=i+1; j<L.size();j++){String date1=L.get(i).getDate();String date2=L.get(j).getDate();Date d1=sdf.parse(date1,new ParsePosition(0));Date d2=sdf.parse(date2,new ParsePosition(0));boolean flag = d1.before(d2);//flag=true为降序,flag=flase为升序if (flag){temp = L.get(i);L.set(i, L.get(j));L.set(j, temp);}}}return L;}//6.0之后要动态获取权限,重要!!!(和获取数据的方法写在一起,第一次获取不到数据,需要刷新或推出再进入)protected void judgePermission() {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {// 检查该权限是否已经获取// 权限是否已经 授权 GRANTED---授权 DINIED---拒绝// sd卡权限String[] SdCardPermission = {Manifest.permission.WRITE_EXTERNAL_STORAGE};if (ContextCompat.checkSelfPermission(this, SdCardPermission[0]) != PackageManager.PERMISSION_GRANTED) {// 如果没有授予该权限,就去提示用户请求ActivityCompat.requestPermissions(this, SdCardPermission, 100);}//手机状态权限String[] readPhoneStatePermission = {Manifest.permission.READ_PHONE_STATE};if (ContextCompat.checkSelfPermission(this, readPhoneStatePermission[0]) != PackageManager.PERMISSION_GRANTED) {// 如果没有授予该权限,就去提示用户请求ActivityCompat.requestPermissions(this, readPhoneStatePermission, 200);}//定位权限String[] locationPermission = {Manifest.permission.ACCESS_FINE_LOCATION};if (ContextCompat.checkSelfPermission(this, locationPermission[0]) != PackageManager.PERMISSION_GRANTED) {// 如果没有授予该权限,就去提示用户请求ActivityCompat.requestPermissions(this, locationPermission, 300);}String[] ACCESS_COARSE_LOCATION = {Manifest.permission.ACCESS_COARSE_LOCATION};if (ContextCompat.checkSelfPermission(this, ACCESS_COARSE_LOCATION[0]) != PackageManager.PERMISSION_GRANTED) {// 如果没有授予该权限,就去提示用户请求ActivityCompat.requestPermissions(this, ACCESS_COARSE_LOCATION, 400);}String[] READ_EXTERNAL_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE};if (ContextCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE[0]) != PackageManager.PERMISSION_GRANTED) {// 如果没有授予该权限,就去提示用户请求ActivityCompat.requestPermissions(this, READ_EXTERNAL_STORAGE, 500);}String[] WRITE_EXTERNAL_STORAGE = {Manifest.permission.WRITE_EXTERNAL_STORAGE};if (ContextCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE[0]) != PackageManager.PERMISSION_GRANTED) {// 如果没有授予该权限,就去提示用户请求ActivityCompat.requestPermissions(this, WRITE_EXTERNAL_STORAGE, 600);}}else{//doSdCardResult();}//LocationClient.reStart();}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);/*** 返回后刷新数据*/adapter.notifyDataSetChanged();}}
实体类Photo.java
public class Photo {private String name;//名称private String date;//日期private long size; //大小private String path;//路径/*** 构造函数*/public Photo() {}public Photo(String name, String date, long size, String path) {this.name = name;this.date = date;this.size = size;this.path = path;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getDate() {return date;}public void setDate(String date) {this.date = date;}public long getSize() {return size;}public void setSize(long size) {this.size = size;}public String getPath() {return path;}public void setPath(String path) {this.path = path;}@Overridepublic String toString() {return "Photo{" +"name='" + name + '\'' +", date='" + date + '\'' +", size=" + size +", path='" + path + '\'' +'}';}
}
RecyclerView适配器 MyAdapter.java
import android.app.Activity;
import android.content.Context;
import android.content.Intent;import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;import com.bumptech.glide.Glide;import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;/*** Created by sp01 on 2017/4/28.*/public class MyAdapter extends RecyclerView.Adapter {private Activity context;public static List<Photo> data;public static List<String> isChecks;public MyAdapter(Activity context) {this.context = context;data = new ArrayList<>();isChecks = new ArrayList<>();}/*** 添加数据* @param data*/public void setData(List<Photo> data) {this.data=data;}@Overridepublic int getItemViewType(int position) {return 1;}@Overridepublic RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {RecyclerView.ViewHolder holder = null;View view = LayoutInflater.from(context).inflate(R.layout.item,parent,false);holder = new OneViewHolder(view);return holder;}@Overridepublic void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {OneViewHolder oneViewHolder = (OneViewHolder) holder;String item = data.get(position).getPath(); //图片地址oneViewHolder.ll_check.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (!isChecks.contains(item)) {// isChecks.clear();if (isChecks.size() <99) {isChecks.add(item);notifyDataSetChanged();}// onImageChecked(mParameters.mMaxCount, checkedList.size());} else {isChecks.remove(item);notifyDataSetChanged();// onImageChecked(mParameters.mMaxCount, checkedList.size());}}});oneViewHolder.imageView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {context.startActivityForResult(new Intent(context, ImagePreviewActivity.class).putExtra("position", position).putExtra("count", 1), MainActivity.ACTION_TO_PREVIEW);}});Glide.with(context) //上下文.asBitmap().centerCrop() //图片中间部分.load(item) //图片地址.error(R.mipmap.qwe) //图片加载出错时显示的图片// .override(500,500) //设置图片宽高.into(oneViewHolder.imageView); //Imageviewif(isChecks.contains(item)){oneViewHolder.tv.setBackgroundResource(R.drawable.bg_green_circle);oneViewHolder.tv.setText((isChecks.indexOf(item)+1)+"");oneViewHolder.imageView.setColorFilter(R.color.black);}else {oneViewHolder.imageView.setColorFilter(1);oneViewHolder.tv.setBackgroundResource(R.drawable.radio_unchecked);oneViewHolder.tv.setText((isChecks.indexOf(item)+1)+"");}}@Overridepublic int getItemCount() {return data != null && data.size() > 0 ? data.size() : 0;}class OneViewHolder extends RecyclerView.ViewHolder{private ImageView imageView;private TextView tv;private LinearLayout ll_check;public OneViewHolder(View itemView) {super(itemView);imageView = (ImageView) itemView.findViewById(R.id.imageView2);tv = itemView.findViewById(R.id.tv_check);ll_check = itemView.findViewById(R.id.ll_check);//方法三:应用程序显示区域指定可能包含应用程序窗口的显示部分,不包括系统装饰DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();int width = displayMetrics.widthPixels;// 动态设置image宽和高ViewGroup.LayoutParams params = imageView.getLayoutParams();params.width = width/4;params.height = width/4;imageView.setLayoutParams(params);}}}
剩下的就是选中图片后的查看大图片了
activity_image_preview.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="match_parent"xmlns:tools="http://schemas.android.com/tools"android:background="#ff000000"tools:context=".ImagePreviewActivity"><androidx.viewpager.widget.ViewPagerandroid:id="@+id/vp_img"android:layout_width="match_parent"android:layout_height="match_parent" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center_vertical"android:orientation="horizontal"><Buttonandroid:id="@+id/btn_back"android:layout_width="45dp"android:layout_height="45dp"android:background="@drawable/back_round" /><TextViewandroid:id="@+id/tv_num"android:background="#9999"android:layout_marginLeft="20dp"android:layout_marginRight="20dp"android:layout_weight="1"android:layout_width="0dp"android:layout_height="wrap_content"android:gravity="center"android:paddingRight="15dp"android:text="0/0"android:textColor="#888"android:textStyle="bold"android:textSize="16sp" /><TextViewandroid:id="@+id/tv_confirm"android:clickable="true"android:background="@drawable/bg_item_type"android:text="@string/complete"android:textColor="#888"android:gravity="center"android:paddingLeft="10dp"android:paddingRight="10dp"android:layout_width="wrap_content"android:layout_margin="5dp"android:layout_height="35dp" /></LinearLayout><ImageViewandroid:id="@+id/ll_check"android:padding="10dp"android:clickable="true"android:src="@drawable/radio_unchecked"android:layout_alignParentBottom="true"android:layout_margin="5dp"android:layout_gravity="right"android:layout_width="40dp"android:layout_height="40dp" /></RelativeLayout>
item_preview.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:background="#000"android:layout_gravity="center"android:orientation="vertical"android:gravity="center"android:layout_width="wrap_content"android:layout_height="wrap_content"><com.github.piasy.biv.view.BigImageViewandroid:id="@+id/iv_item2"android:layout_width="match_parent"android:layout_height="match_parent"app:failureImageInitScaleType="center"app:optimizeDisplay="true" /></LinearLayout>
ImagePreviewActivity.java
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.ViewPager;import com.github.piasy.biv.BigImageViewer;
import com.github.piasy.biv.loader.fresco.FrescoImageLoader;public class ImagePreviewActivity extends AppCompatActivity {Context mContext;ViewPager vpImg;Button btBack;TextView tvNum;TextView tvConfirm;ImageView ivCheck;View.OnClickListener onClickListener;PreviewAdapter previewAdapter;int count;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mContext = this;BigImageViewer.initialize(FrescoImageLoader.with(mContext));setContentView(R.layout.activity_image_preview);setNoTitle();findViewById();setAdapter();setNum();}private void setNum() {count = getIntent().getIntExtra("count", 2);tvNum.setText(MyAdapter.isChecks.size() + "/" + 99);if (MyAdapter.isChecks.size() == 0) {tvNum.setTextColor(Color.parseColor("#808080"));tvConfirm.setTextColor(Color.parseColor("#808080"));tvConfirm.setBackgroundResource(R.drawable.bg_item_type);} else {tvNum.setTextColor(Color.parseColor("#f0f0f0"));tvConfirm.setTextColor(Color.parseColor("#f0f0f0"));tvConfirm.setBackgroundResource(R.drawable.bg_confirm);}}private void setAdapter() {previewAdapter = new PreviewAdapter();vpImg.setAdapter(previewAdapter);vpImg.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}@Overridepublic void onPageSelected(int position) {if (MyAdapter.isChecks.contains(MyAdapter.data.get(position).getPath())) {ivCheck.setImageResource(R.drawable.radio_checked);} else {ivCheck.setImageResource(R.drawable.radio_unchecked);}}@Overridepublic void onPageScrollStateChanged(int state) {}});vpImg.setCurrentItem(getIntent().getIntExtra("position", 0));}private void findViewById() {vpImg = findViewById(R.id.vp_img);btBack = findViewById(R.id.btn_back);tvNum = findViewById(R.id.tv_num);tvConfirm = findViewById(R.id.tv_confirm);ivCheck = findViewById(R.id.ll_check);onClickListener = new View.OnClickListener() {@Overridepublic void onClick(View v) {if (v.getId() == R.id.btn_back) {finish();} else if (v.getId() == R.id.tv_confirm) {setResult(RESULT_OK);finish();} else if (v.getId() == R.id.ll_check) {String item = MyAdapter.data.get(vpImg.getCurrentItem()).getPath();if (MyAdapter.isChecks.contains(item)) {MyAdapter.isChecks.remove(item);ivCheck.setImageResource(R.drawable.radio_unchecked);} else {if (MyAdapter.isChecks.size() < 99) {MyAdapter.isChecks.add(item);ivCheck.setImageResource(R.drawable.radio_checked);}}setNum();}}};btBack.setOnClickListener(onClickListener);tvConfirm.setOnClickListener(onClickListener);ivCheck.setOnClickListener(onClickListener);}private void setNoTitle() {getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//去掉信息栏getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);try {getSupportActionBar().hide();} catch (Exception e) {}}@Overrideprotected void onDestroy() {super.onDestroy();BigImageViewer.imageLoader().cancelAll();}}
pagerView适配器 PreviewAdapter.java
import android.net.Uri;import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;import androidx.annotation.NonNull;
import androidx.viewpager.widget.PagerAdapter;import com.bumptech.glide.Glide;
import com.github.piasy.biv.indicator.progresspie.ProgressPieIndicator;
import com.github.piasy.biv.view.BigImageView;
import com.github.piasy.biv.view.FrescoImageViewFactory;import java.io.File;public class PreviewAdapter extends PagerAdapter {@Overridepublic int getCount() {return MyAdapter.data.size();}@Overridepublic boolean isViewFromObject(@NonNull View view, @NonNull Object object) {return view == object;}@Overridepublic Object instantiateItem(ViewGroup container, int position) {String item = MyAdapter.data.get(position).getPath();System.out.println("图片路径:"+item);View itemView = LayoutInflater.from(container.getContext()).inflate(R.layout.item_preview, null);container.addView(itemView);BigImageView ivItem = (BigImageView) itemView.findViewById(R.id.iv_item2);// 获取手机本地图片ivItem.showImage(Uri.fromFile(new File(item)));// 获取网络图片// ivItem.showImage(Uri.parse(("https://img2.woyaogexing.com/2023/03/03/2b7c846abc54f1a8c10e683951ccbc8c.jpg")));ivItem.setImageViewFactory(new FrescoImageViewFactory());ivItem.setProgressIndicator(new ProgressPieIndicator());return itemView;}@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {container.removeView((View) object);}}
以上就是所有的代码了。
相关文章:

Android仿微信选择图片
效果展示首先先添加用到的权限<uses-permission android:name"android.permission.INTERNET" /><!--获取手机存储卡权限--><uses-permission android:name"android.permission.READ_EXTERNAL_STORAGE"/><uses-permission android:nam…...

python+嵌入式——串口通信篇(收发解包)
目录前言安装pyserialpyserial大致概括整体流程硬件连接例子(简单版)详细使用serial初始化参数发包收包收包检查包并解包python struct模块结语前言 这几年,自己也做了一些嵌入式机器人。在整个开发的过程中,调通信通常会花费一段比较长的时间ÿ…...

剖析G1 垃圾回收器
简单回顾 在Java当中,程序员在编写代码的时候只需要创建对象,从来不需要考虑将对象进行释放,这是因为Java中对象的垃圾回收全部由JVM替你完成了(所有的岁月静好都不过是有人替你负重前行)。 而JVM的垃圾回收由垃圾回收器来负责,在…...

如何打造一款专属于自己的高逼格电脑桌面
作为一名电脑重度使用者,你是否拥有一款属于你自己的高逼格电脑桌面呢?你是不是也像大多数同学一样,会把所有的内容全部都堆积到电脑桌面,不仅找东西困难,由于桌面内容太多还会导致C盘空间不足,影响电脑的反…...

【C++】string的使用及其模拟实现
文章目录1. STL的介绍1.1 STL的六大组件1.2 STL的版本1.3 STL的缺陷2. string的使用2.1 为什么要学习string类?2.2 常见构造2.3 Iterator迭代器2.4 Capacity2.5 Modifiers2.6 String operations3. string的模拟实现3.1 构造函数3.2 拷贝构造函数3.3 赋值运算符重载和…...
怀念在青鸟的日子
时间过的可真快,一转眼来到了2023年!我初中上完就没有在念,下了学门步入社会,那时的我一片迷茫,不知道该去干什 么,父母说要不去学挖掘机、理发、修车...我思考再三,一个都没有我喜欢的…...
学习记录---Python内置类型
文章目录字符串split()列表常见操作列表相减字典创建普通创建eval(s)添加或更新元素d[t] 1d.update({c: 3}){**d1, **d2} **字典解包装运算符删除元素 d.pop(c)属性d.items()d.keys()d.values()访问元素d[Name]d.get(score)遍历字典for key in dictfor key, values in dict.it…...

Python笔记 -- 列表
文章目录1、列表简介2、修改、添加、删除元素2.1、添加2.2、删除3、排序、倒序4、遍历列表5、创建数值列表6、列表切片7、列表复制8、元组1、列表简介 在Python中用方括号[]表示列表,用逗号隔开表示其元素 通过索引访问列表 names [aa,bb,cc,dd]print(names[0]) …...
谈谈UVM中的uvm_info打印
uvm_info宏的定义如下: define uvm_info(ID,MSG,VERBOSITY) \begin \if (uvm_report_enabled(VERBOSITY,UVM_INFO,ID)) \uvm_report_info (ID, MSG, VERBOSITY, uvm_file, uvm_line); \end 从这里可以看出uvm_info由两部分组成:uvm_report_enabled(VER…...
矩阵理论1 集合上的等价关系(equivalence relations on a set S)
定义 对于一个集合S, 如果集合E⊂SS\mathcal{E} \subset S\times SE⊂SS满足以下条件 自反性: 对于∀s∈S,都有(s,s)∈E\forall s\in S, 都有 (s, s) \in \mathcal{E}∀s∈S,都有(s,s)∈E对称性: (s,t)∈E⇔(t,s)∈E(s,t) \in \mathcal{E} \Leftrightarrow (t,s)\in \mathcal…...

【网络监控】Zabbix详细安装部署(最全)
文章目录Zabbix详细安装部署环境准备安装依赖组件访问初始化配置Zabbix详细安装部署 Zabbix 是一个高度集成的网络监控解决方案,可以提供企业级的开源分布式监控解决方案,由一个国外的团队持续维护更新,软件可以自由下载使用,运作…...

阿里云轻量服务器--Docker--Nacos安装(使用外部Mysql数据存储)
前言:docker 安装nacos 如果不设置外部的mysql 默认使用内嵌的内嵌derby为数据源,这个时候如果,重新部署nacos 则会造成原有数据丢失情况; 1 默认安装的nacos 启动后使用的是内嵌的存储: 2 使用外部mysql 作为存储&a…...

unity开发知识点小结01
unity对象生命周期函数 Awake():最早调用,所以可以实现单例模式 OnEnable():组件激活后调用,在Awake后调用一次 Stat():在Update()之前,OnEnable…...
软件系统[软件工程]
What’s the link? They all involve outdated (legacy) software technology. All have had huge socio-economical impact. Prompting national lockdowns. Spreadsheet workflow error led to thousands of preventable infections and deaths. Huge losses of citizen dat…...

电力系统稳定性的定义与分类
1电力系统稳定性的定义与分类 IEEE给出电力系统稳定性定义:电力系统稳定性是指电力系统这样的一种能力—对于给定的初始运行状态,经历物理扰动后,系统能够重新获得运行平衡点的状态,同时绝大多数系统变量有界,因此整个…...

基于java的俱乐部会员管理系统
技术:Java、JSP等摘要:随着科学技术的飞速发展,科学技术在人们日常生活中的应用日益广泛,也给各行业带来发展的机遇,促使各个行业给人们提供更加优质的服务,有效提升各行业的管理水平。俱乐部通过使用一定的…...

线程池执行父子任务,导致线程死锁
前言, 一次线程池的不当使用,导致了现场出现了线程死锁,接口一直不返回。而且由于这是一个公共的线程池,其他使用了次线程池的业务也一直阻塞,系统出现了OOM,不过是幸好是线程同事测试出来的,没…...

Ubuntu系统新硬盘挂载
Ubuntu系统新硬盘挂载 服务器通常会面临存储不足的问题,大部分服务器都是ubuntu系统,该篇博客浅浅记载一下在ubuntu系统上挂载新硬盘的步骤。本篇博文仅仅记载简单挂载一块新的硬盘,而没有对硬盘进行分区啥的。如果需要更加完善的教程&#…...

【亲测】Centos7系统非管理(root)权限编译NCNN
前言 由于使用的是集群,自己不具有管理员权限,所以以下所有的情况均在非管理员权限下进行安装,即该安装策略仅适用于普通用户构建自己的环境。 什么是NCNN ncnn是一款非常高效易用的深度学习推理框架,支持各种神经网络模型&#x…...
四种常见的异步请求方式
四种常见的异步请求方式 一、xhr异步老祖 XMLHttpRequest(简称XHR)是一种在JavaScript中创建异步请求的技术。XHR对象可以向服务器发送请求,并获取服务器返回的数据,而不会使页面刷新。 XHR对象的创建方式通常是通过构造…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...