学会使用RecyclerView 及Arrays.asList函数

本文介绍了如何使用RecyclerView组件实现ListView的循环滚动效果,包括布局管理器LinearLayoutManager的配置,自定义Adapter的实现,以及避免使用Arrays.asList方法不当导致的UnsupportedOperationException问题。

要实现ListView列表的循环滚动效果,其实可以用RecyclerView实现。

Runnable run = new Runnable() {
		
		@Override
		public void run() {
//			String str = "abc";
//			datas.add(str);
//			mRecyclerAdapter.notifyItemInserted(1);
			datas.remove(curPos);
			mRecyclerAdapter.notifyItemRemoved(curPos);
			curPos --;
			handler.sendEmptyMessage(0);
		}
	};


布局文件中使用 RecyclerView,横向和纵向两个:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MyActivity">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="Horizontal"
        android:textSize="18sp" />
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerview_horizontal"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:scrollbars="horizontal" />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="Vertical"
        android:textSize="18sp" />
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerview_vertical"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:scrollbars="vertical" />
</LinearLayout>

Activity中

package com.baoyz.recyclerviewdemo;
import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuItem;
public class MyActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);
        initHorizaontal();
        initVertical();
    }
    private void initHorizaontal() {
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview_horizontal);
        // 创建一个线性布局管理器
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        // 设置布局管理器
        recyclerView.setLayoutManager(layoutManager);
        // 创建数据集
        String[] dataset = new String[100];
        for (int i = 0; i < dataset.length; i++){
            dataset[i] = "item" + i;
        }
        // 创建Adapter,并指定数据集
        MyAdapter adapter = new MyAdapter(dataset);
        // 设置Adapter
        recyclerView.setAdapter(adapter);
    }
    public void initVertical(){
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview_vertical);
        // 创建一个线性布局管理器
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        // 默认是Vertical,可以不写
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        // 设置布局管理器
        recyclerView.setLayoutManager(layoutManager);
        // 创建数据集
        String[] dataset = new String[100];
        for (int i = 0; i < dataset.length; i++){
            dataset[i] = "item" + i;
        }
        // 创建Adapter,并指定数据集
        MyAdapter adapter = new MyAdapter(dataset);
        // 设置Adapter
        recyclerView.setAdapter(adapter);
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
}

RecyclerView 一个特点就是,将 layout 抽象成了一个 LayoutManager,RecylerView 不负责子 View 的布局, 我们可以自定义 LayoutManager 来实现不同的布局效果, 目前只提供了LinearLayoutManager。 LinearLayoutManager 可以指定方向,默认是垂直, 可以指定水平, 这样就轻松实现了水平的 ListView。
Adapter

package com.baoyz.recyclerviewdemo;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
 * Created by baoyz on 2014/6/29.
 */
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>{
    // 数据集
    private String[] mDataset;
    public MyAdapter(String[] dataset) {
        super();
        mDataset = dataset;
    }
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        // 创建一个View,简单起见直接使用系统提供的布局,就是一个TextView
        View view = View.inflate(viewGroup.getContext(), android.R.layout.simple_list_item_1, null);
        // 创建一个ViewHolder
        ViewHolder holder = new ViewHolder(view);
        return holder;
    }
    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int i) {
        // 绑定数据到ViewHolder上
        viewHolder.mTextView.setText(mDataset[i]);
    }
    @Override
    public int getItemCount() {
        return mDataset.length;
    }
    public static class ViewHolder extends RecyclerView.ViewHolder{
        public TextView mTextView;
        public ViewHolder(View itemView) {
            super(itemView);
            mTextView = (TextView) itemView;
        }
    }
}

RecyclerView 的另一个特点是标准化了 ViewHolder, 编写 Adapter 面向的是 ViewHoder 而不在是View 了, 复用的逻辑被封装了, 写起来更加简单。

惭愧,使用Arrays.as(String[])方法不当,调试半天不知道哪错了:

试运行如下代码,你猜会出现什么情况。

  public static void main(String[] args){
        String[] strs={"1","2","3","4"};
        System.out.println(Arrays.asList(strs).remove(0));
    }

如果没有没错,你一般会说是:1。但是实际上返回的是:

Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.AbstractList.remove(AbstractList.java:144)
    at com.lmax.disruptor.YieldingWaitStrategy.main(YieldingWaitStrategy.java:126)

 

为什么会出现这种情况?因为我们认为JDK会返回一个ArrayList或者LinkedList,所直接调用remove(int index)方法。实际上asList返回的时什么呢?asList返回的是Arrays类内部自定义的AbstractList的子类,它没有实现remove方法。

如何避免这种情况发生呢?

 public static void main(String[] args){
        String[] strs={"1","2","3","4"};
        System.out.println(new LinkedList<String>(Arrays.asList(strs)).remove(0));
    }

 

package com.example.myapplication; import android.os.Bundle; import android.view.View; import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.example.myapplication.adapters.StudentAdapter; import com.example.myapplication.models.Student; import java.util.Random; // 文件顶部添加 import java.util.ArrayList; import java.util.List; import java.util.Arrays; import java.util.List; public class MainActivity extends AppCompatActivity { private RecyclerView recyclerView; private StudentAdapter adapter; private List<Student> studentList = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); EdgeToEdge.enable(this); setContentView(R.layout.activity_main); ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); return insets; // 初始化学生数据 initStudents(); recyclerView = findViewById(R.id.rv_students); recyclerView.setLayoutManager(new LinearLayoutManager(this)); // 正确做法:先创建数组再转换 Student[] stuArray = {new Student("张三"), new Student("李四")}; List<Student> correctList = Arrays.asList(stuArray); // ✅正确初始化[^1] recyclerView.setAdapter(adapter); }); } private void initStudents() { for (int i = 1; i <= 40; i++) { studentList.add(new Student( "学生" + i, "2024" + String.format("%03d", i), new Random().nextBoolean() )); } } // 在MainActivity中添加 public void onAddScoreClick(View view) { int position = recyclerView.getChildLayoutPosition((View) view.getParent()); Student student = studentList.get(position); switch(view.getId()) { case R.id.btn_add_1: student.getTotalScore(student.getTotalScore() + 1); break; case R.id.btn_add_2: student.getTotalScore(student.getTotalScore() + 2); break; } adapter.notifyItemChanged(position); } public void adjustBaseScore(int newBase) { // 遍历方式1:增强for循环 for (Student s : students) { System.out.println(s.getTotalScore()); // ✅对象.方法() } // 遍历方式2:Lambda表达式 students.forEach(s -> System.out.println(s.getTotalScore() + 1) // ✅正确调用位置 ); } } MainActivity package com.example.myapplication.models; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class Student { private String name; private String studentId; private double baseScore = 50; private double additionalScore = 0; private boolean isMale; private String gender; private double totalScore; public Student(String name, String studentId, boolean isMale) { this.name = name; this.studentId = studentId; this.isMale = isMale; } // ✅必须存在且可见的访问方法 public double getTotalScore() { return this.totalScore; } public Student(String name) { this.name = name; this.totalScore = Math.random() * 100; // 模拟分数 } public String getStudentId() { return studentId; } public String getName() { return name; } public boolean isMale() { return "男".equals(this.gender); // gender字段需存在 } public Object getAdditionalScore() { return this.baseScore + this.additionalScore; // 根据实际字段调整 } public void setBaseScore(int baseScore) { this.baseScore = baseScore; // 确保baseScore字段存在 } // Getter/Setter省略 public class Main { public static void main(String[] args) { // 1. 正确初始化List Student[] stuArray = { new Student("张三"), new Student("李四") }; List<Student> fixedList = Arrays.asList(stuArray); // 2. 转换为可变List List<Student> mutableList = new ArrayList<>(fixedList); mutableList.add(new Student("王五")); // ✅允许新增 // 3. 正确调用对象方法 System.out.println("-----成绩列表-----"); mutableList.forEach(s -> System.out.printf("%s: %.1f分%n", s.getName(), s.getTotalScore() + 2 // ✅正确调用位置 ) ); } } Student 以上是我目前的代码,报错地方有很多,但是我都不知道怎么修改
05-14
package com.example.ju_net; import androidx.activity.result.ActivityResult; import androidx.activity.result.ActivityResultCallback; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import android.annotation.TargetApi; import android.app.Activity; import android.app.AlertDialog; import android.content.ClipData; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.ImageFormat; import android.hardware.camera2.CameraAccessException; import android.hardware.camera2.CameraCaptureSession; import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CameraDevice; import android.hardware.camera2.CameraManager; import android.hardware.camera2.CaptureRequest; import android.media.Image; import android.media.ImageReader; import android.media.MediaScannerConnection; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.HandlerThread; import android.provider.MediaStore; //import android.support.annotation.NonNull; //import android.support.v4.app.ActivityCompat; import android.util.Log; import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.Toast; import androidx.activity.EdgeToEdge; import androidx.annotation.NonNull; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.Locale; import java.util.Map; import okhttp3.Call; import okhttp3.Callback; import okhttp3.Headers; import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; public class MainActivity extends AppCompatActivity { private ActivityResultLauncher<Intent> activityResultLauncher; private static final int CODE_SELECT_IMAGE = 1; private CameraManager mCameraManager; private SurfaceView mSurfaceView; private SurfaceHolder mSurfaceViewHolder; private Handler mHandler; private String mCameraId; private ImageReader mImageReader; private CameraDevice mCameraDevice; private CaptureRequest.Builder mPreviewBuilder; private CameraCaptureSession mSession; private RecyclerView recyclerView; private PhotoAdapter photoAdapter; private List<String> photoPaths = new ArrayList<>(); private Button take_picture_bt, mOpenPhoto, mUploadPhoto; private Handler mainHandler; private static final String TAG = "CameraFragment"; private String mPublicPhotoPath = ""; //创建okHttpClient对象 OkHttpClient mOkHttpClient = new OkHttpClient(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); EdgeToEdge.enable(this); setContentView(R.layout.activity_main); ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.hide(); } recyclerView = findViewById(R.id.recycler_view); // img_show = (ImageView) findViewById(R.id.img_show); take_picture_bt = (Button) findViewById(R.id.take_picture); mOpenPhoto = (Button) findViewById(R.id.open_photo); mUploadPhoto = (Button) findViewById(R.id.upload_photo); mUploadPhoto.setEnabled(false); // 初始化RecyclerView photoAdapter = new PhotoAdapter(this, photoPaths); recyclerView.setLayoutManager(new GridLayoutManager(this, 3)); recyclerView.setAdapter(photoAdapter); // 注册 Activity Result Launcher activityResultLauncher = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), result -> handleGalleryResult(result) ); initSurfaceView();//初始化SurfaceView /** * 拍照按钮监听 */ take_picture_bt.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { takePicture(); } }); mOpenPhoto.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent albumIntent = new Intent(Intent.ACTION_GET_CONTENT); albumIntent.setType("image/*"); albumIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); // 允许多选 activityResultLauncher.launch(albumIntent); } }); mUploadPhoto.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // 通过AlertDialog.Builder这个类来实例化我们的一个AlertDialog的对象 AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); // 设置Title的图标 builder.setIcon(R.drawable.ic_launcher_background); // 设置Title的内容 builder.setTitle("提示框"); // 设置Content来显示一个信息 builder.setMessage("确定上传吗?"); // 设置一个PositiveButton builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Log.i(TAG, mPublicPhotoPath); if (mPublicPhotoPath == "") { return; } File file = new File(mPublicPhotoPath); Request request = getFileRequest("http://192.168.11.13:10004/api/upload", file, null); Call call = mOkHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.i(TAG, "上传失败!"); } @Override public void onResponse(Call call, Response response) throws IOException { String result = response.body().string(); parseJSONWithGSON(result); //显示UI界面,调用的showResponse方法 Log.i(TAG, result.toString()); //Toast.makeText(MainActivity.this, "success!", Toast.LENGTH_SHORT).show(); } }); } }); // 设置一个NegativeButton builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //Toast.makeText(MainActivity.this, "negative: " + which, Toast.LENGTH_SHORT).show(); } }); // 设置一个NeutralButton // 显示出该对话框 builder.show(); } }); ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); return insets; }); } private void handleGalleryResult(ActivityResult result) { if (result.getResultCode() == RESULT_OK && result.getData() != null) { Intent data = result.getData(); if (data.getClipData() != null) { // 多选 ClipData clipData = data.getClipData(); for (int i = 0; i < clipData.getItemCount(); i++) { Uri imageUri = clipData.getItemAt(i).getUri(); String path = getRealPathFromURI(imageUri); if (!photoPaths.contains(path)) { photoPaths.add(path); } } } else if (data.getData() != null) { // 单选 Uri imageUri = data.getData(); String path = getRealPathFromURI(imageUri); if (!photoPaths.contains(path)) { photoPaths.add(path); } } photoAdapter.notifyDataSetChanged(); } } private String getRealPathFromURI(Uri contentUri) { Cursor cursor = getContentResolver().query(contentUri, null, null, null, null); if (cursor == null) return contentUri.getPath(); cursor.moveToFirst(); int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); String path = cursor.getString(idx); cursor.close(); return path; } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if(requestCode == 1){ for (int grantResult : grantResults) { if(grantResult != PackageManager.PERMISSION_GRANTED){ Toast.makeText(this, "对不起,没有权限,无法正常使用相机", Toast.LENGTH_SHORT).show(); return; }else{ System.out.println("正常使用相机!"); } } initCameraAndPreview(); } } public void initSurfaceView() { mSurfaceView = (SurfaceView) findViewById(R.id.mFirstSurfaceView); mSurfaceViewHolder = mSurfaceView.getHolder();//通过SurfaceViewHolder可以对SurfaceView进行管理 mSurfaceViewHolder.addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { initCameraAndPreview(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { //释放camera if (mCameraDevice != null) { mCameraDevice.close(); mCameraDevice = null; } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } }); } @TargetApi(19) public void initCameraAndPreview() { HandlerThread handlerThread = new HandlerThread("My First Camera2"); handlerThread.start(); mHandler = new Handler(handlerThread.getLooper()); mainHandler = new Handler(getMainLooper());//用来处理ui线程的handler,即ui线程 mCameraManager = (CameraManager) this.getSystemService(Context.CAMERA_SERVICE); try { mCameraId = "" + CameraCharacteristics.LENS_FACING_FRONT; mImageReader = ImageReader.newInstance(mSurfaceView.getWidth(), mSurfaceView.getHeight(), ImageFormat.JPEG,/*maxImages*/7); mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mainHandler);//这里必须传入mainHandler,因为涉及到了Ui操作 if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (checkSelfPermission(android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED || checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[]{android.Manifest.permission.CAMERA, android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); } } return; } mCameraManager.openCamera(mCameraId, deviceStateCallback, mHandler); } catch (CameraAccessException e) { Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show(); } } private ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() { @Override public void onImageAvailable(ImageReader reader) { //进行相片存储 //mCameraDevice.close(); Image image = reader.acquireNextImage(); ByteBuffer buffer = image.getPlanes()[0].getBuffer(); byte[] bytes = new byte[buffer.remaining()]; buffer.get(bytes);//将image对象转化为byte,再转化为bitmap final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); if (bitmap != null) { //img_show.setImageBitmap(bitmap); mUploadPhoto.setEnabled(true); } savePicture(bytes); } }; private CameraDevice.StateCallback deviceStateCallback = new CameraDevice.StateCallback() { @Override public void onOpened(CameraDevice camera) { mCameraDevice = camera; try { takePreview(); } catch (CameraAccessException e) { e.printStackTrace(); } } @Override public void onDisconnected(@NonNull CameraDevice camera) { if (mCameraDevice != null) { mCameraDevice.close(); mCameraDevice = null; } } @Override public void onError(CameraDevice camera, int error) { Toast.makeText(MainActivity.this, "打开摄像头失败", Toast.LENGTH_SHORT).show(); } }; public void takePreview() throws CameraAccessException { mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); mPreviewBuilder.addTarget(mSurfaceViewHolder.getSurface()); mCameraDevice.createCaptureSession(Arrays.asList(mSurfaceViewHolder.getSurface(), mImageReader.getSurface()), mSessionPreviewStateCallback, mHandler); } private CameraCaptureSession.StateCallback mSessionPreviewStateCallback = new CameraCaptureSession.StateCallback() { @Override public void onConfigured(@NonNull CameraCaptureSession session) { mSession = session; //配置完毕开始预览 try { /** * 设置你需要配置的参数 */ //自动对焦 mPreviewBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); //打开闪光灯 mPreviewBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); //无限次的重复获取图像 mSession.setRepeatingRequest(mPreviewBuilder.build(), null, mHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } @Override public void onConfigureFailed(@NonNull CameraCaptureSession session) { Toast.makeText(MainActivity.this, "配置失败", Toast.LENGTH_SHORT).show(); } }; public void takePicture() { try { CaptureRequest.Builder captureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);//用来设置拍照请求的request captureRequestBuilder.addTarget(mImageReader.getSurface()); // 自动对焦 captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); // 自动曝光 captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); int rotation = getWindowManager().getDefaultDisplay().getRotation(); CameraCharacteristics cameraCharacteristics = mCameraManager.getCameraCharacteristics(mCameraId); captureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION, getJpegOrientation(cameraCharacteristics, rotation));//使图片做顺时针旋转 CaptureRequest mCaptureRequest = captureRequestBuilder.build(); mSession.capture(mCaptureRequest, null, mHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } //获取图片应该旋转的角度,使图片竖直 public int getOrientation(int rotation) { switch (rotation) { case Surface.ROTATION_0: return 90; case Surface.ROTATION_90: return 0; case Surface.ROTATION_180: return 270; case Surface.ROTATION_270: return 180; default: return 0; } } //获取图片应该旋转的角度,使图片竖直 private int getJpegOrientation(CameraCharacteristics c, int deviceOrientation) { if (deviceOrientation == android.view.OrientationEventListener.ORIENTATION_UNKNOWN) return 0; int sensorOrientation = c.get(CameraCharacteristics.SENSOR_ORIENTATION); // Round device orientation to a multiple of 90 deviceOrientation = (deviceOrientation + 45) / 90 * 90; // LENS_FACING相对于设备屏幕的方向,LENS_FACING_FRONT相机设备面向与设备屏幕相同的方向 boolean facingFront = c.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT; if (facingFront) deviceOrientation = -deviceOrientation; // Calculate desired JPEG orientation relative to camera orientation to make // the image upright relative to the device orientation int jpegOrientation = (sensorOrientation + deviceOrientation + 360) % 360; return jpegOrientation; } //将照片存储在相机照片存储位置,这里采用bitmap方式保存 public String savePicture(byte[] imgBytes) { String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(new Date()); String imgPath = Environment.getExternalStorageDirectory() + "/DCIM/JPEG_" + timeStamp + ".jpg"; try (FileOutputStream outputStream = new FileOutputStream(imgPath)) { outputStream.write(imgBytes); photoPaths.add(imgPath); photoAdapter.notifyDataSetChanged(); MediaScannerConnection.scanFile(this, new String[]{imgPath}, null, null); } catch (IOException e) { e.printStackTrace(); } return timeStamp; } public static Request getFileRequest(String url, File file, Map<String, String> maps){ MultipartBody.Builder builder= new MultipartBody.Builder().setType(MultipartBody.FORM); if(maps==null){ builder.addPart( Headers.of("Content-Disposition", "form-data; name=\"file\";filename=\"file.jpg\""), RequestBody.create(MediaType.parse("image/png"),file) ).build(); }else{ for (String key : maps.keySet()) { builder.addFormDataPart(key, maps.get(key)); } builder.addPart( Headers.of("Content-Disposition", "form-data; name=\"file\";filename=\"file.jpg\""), RequestBody.create(MediaType.parse("image/png"),file) ); } RequestBody body=builder.build(); return new Request.Builder().url(url).post(body).build(); } private void parseJSONWithGSON(String jsonData) { //使用轻量级的Gson解析得到的json Gson gson = new Gson(); UploadResult uploadResult = gson.fromJson(jsonData, new TypeToken<UploadResult>() {}.getType()); //控制台输出结果,便于查看 Log.d("MainActivity", "status" + uploadResult.getStatus()); Log.d("MainActivity", "msg" + uploadResult.getMsg()); } }逐段分析所有代码
06-18
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值