图文上传+多张图片选择

 网址:https://github.com/LuckSiege/PictureSelector#%E5%B8%B8%E8%A7%81%E9%94%99%E8%AF%AF

依赖

implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.2.3'
1.BaseApis
    //发表帖子
    @POST
    Observable<ResponseBody> imagepost(@Url String url, @QueryMap HashMap<String, String> map, @Body MultipartBody parts);

2.RetorfitManager

 private MultipartBody build;
 //发表帖子
    public void imagepost(String url, HashMap<String,String> map, List<File> file, ICallBack callBack){
        if(file.size()>0){
            MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
            for (int i = 0; i < file.size(); i++) {
                builder.addFormDataPart("file", file.get(i).getName(), RequestBody.create(MediaType.parse("image/*"), file.get(i)));
            }
            build = builder.build();
        }else{
            build=new MultipartBody.Builder()
                    .setType(MultipartBody.FORM)
                    .addFormDataPart("","")
                    .build();
        }

        baseApis.imagepost(url, map,build)
                .subscribeOn(Schedulers.io())//io子线程
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(getObserver(callBack));
    }

Activity
    MultipartBody.Builder builder=new MultipartBody.Builder().setType(MultipartBody.FORM);
                        if(name.equals(""))
                        {
                            Toast.makeText(this, "请输入发表的内容!", Toast.LENGTH_SHORT).show();
                        }else
                        {
                            for (int i = 0; i <files.size() ; i++) {
                                builder.addFormDataPart("file",files.get(i).getName(),RequestBody.create(MediaType.parse("image/*"),files.get(i)));
                            }
                            HashMap<String,String> map=new HashMap<>();
                            map.put("content",name);
                            //MultipartBody build=builder.build();
                            iPresentermpl.imagepost(Api.RELEASEPOST,map,files,NewsReplaceBean.class);
                        }

2.Ativity



public class NewsMessageActivity extends AppCompatActivity implements IView {

@BindView(R.id.edit_num)
    TextView edit_num;
    @BindView(R.id.messagecontent)
    EditText messagecontent;
    @BindView(R.id.recycler)
    RecyclerView recycler;
    PopupWindow popupWindow;
    @BindView(R.id.messageok)
    TextView messageok;
    @BindView(R.id.message_qx)
            TextView message_qx;
    @BindView(R.id.messqge_yuyin)
    TextView messqge_yuyin;
    public  final static int VEDIO_KU = 101;
    IPresentermpl iPresentermpl;
    private final int REQUEST_PICK = 200;
    private final int REQUEST_CAMEAR = 100;
    private final int REQUEST_PICTRUE = 300;
    private final String PATH_FILE = Environment.getExternalStorageDirectory() + "/file.png";
   // private final String path = Environment.getExternalStorageDirectory() + "/image.png";

    private int maxSelectNum = 9;
    private List<LocalMedia> selectList = new ArrayList<>();
    private GridImageAdapter adapter;
    private PopupWindow pop;
    private String path;
    private  List<File> files=new ArrayList<>();

    private String userId,sessionId;
    private SharedPreferences sharedPreferences;
    String[] permissions = new String[]{
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.CAMERA,
            Manifest.permission.INTERNET};
    List<String> mPermissionList = new ArrayList<>();
    private final int mRequestCode = 100;//权限请求码
    AlertDialog mPermissionDialog;
    String mPackName = "com.wd.tech";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_news_message);
        ButterKnife.bind(this);
        iPresentermpl=new IPresentermpl(this);
        //Appid

        sharedPreferences = getSharedPreferences("User", MODE_PRIVATE);
        userId = sharedPreferences.getString("userId", "");
        sessionId = sharedPreferences.getString("sessionId", "");
        //输入
        messagecontent.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }
            @Override
            public void afterTextChanged(Editable s) {
                edit_num.setText(String.valueOf(s.length()) + "/300");
                if (s.length() >= 300) {
                    Toast.makeText(NewsMessageActivity.this, "上限了,亲", Toast.LENGTH_SHORT).show();
                }
            }
        });   //逐个判断是否还有未通过的权限
        for (int i = 0;i<permissions.length;i++){
            if (ContextCompat.checkSelfPermission(this,permissions[i])!=
                    PackageManager.PERMISSION_GRANTED){
                mPermissionList.add(permissions[i]);//添加还未授予的权限到mPermissionList中
            }
        }
        //申请权限
        if (mPermissionList.size()>0){//有权限没有通过,需要申请
            ActivityCompat.requestPermissions(this,permissions,mRequestCode);
        }else {
            //权限已经都通过了,可以将程序继续打开了
            initWidget();
        }





    }




    @OnClick({R.id.recycler,R.id.messageok,R.id.message_qx,R.id.messqge_yuyin})
        public  void  setlick(View view)
        {
                switch (view.getId())
                {
                    case R.id.recycler:
                        break;
                    case R.id.messageok:
                        String name=messagecontent.getText().toString();

                        MultipartBody.Builder builder=new MultipartBody.Builder().setType(MultipartBody.FORM);
                        if(name.equals(""))
                        {
                            Toast.makeText(this, "请输入发表的内容!", Toast.LENGTH_SHORT).show();
                        }else
                        {
                            for (int i = 0; i <files.size() ; i++) {
                                builder.addFormDataPart("file",files.get(i).getName(),RequestBody.create(MediaType.parse("image/*"),files.get(i)));
                            }
                            HashMap<String,String> map=new HashMap<>();
                            map.put("content",name);
                            //MultipartBody build=builder.build();
                            iPresentermpl.imagepost(Api.RELEASEPOST,map,files,NewsReplaceBean.class);
                        }
                        finish();
                        break;
                    case R.id.message_qx:
                            finish();
                        break;

                        default:break;
                }
        }
public  void  initWidget()
{
    FullyGridLayoutManager manager = new FullyGridLayoutManager(this, 3, GridLayoutManager.VERTICAL, false);
    recycler.setLayoutManager(manager);
    adapter = new GridImageAdapter(this, onAddPicClickListener);
    adapter.setList(selectList);
    adapter.setSelectMax(maxSelectNum);
    recycler.setAdapter(adapter);
    adapter.setOnItemClickListener(new GridImageAdapter.OnItemClickListener() {
        @Override
        public void onItemClick(int position, View v) {
            if (selectList.size() > 0) {
                LocalMedia media = selectList.get(position);
                String pictureType = media.getPictureType();
                int mediaType = PictureMimeType.pictureToVideo(pictureType);
                switch (mediaType) {
                    case 1:
                        // 预览图片 可自定长按保存路径
                        //PictureSelector.create(MainActivity.this).externalPicturePreview(position, "/custom_file", selectList);
                        PictureSelector.create(NewsMessageActivity.this).externalPicturePreview(position, selectList);
                        Log.i("aaaaaa地址",selectList+"");
                        break;
                    case 2:
                        // 预览视频
                        PictureSelector.create(NewsMessageActivity.this).externalPictureVideo(media.getPath());
                        break;
                    case 3:
                        // 预览音频

                        PictureSelector.create(NewsMessageActivity.this).externalPictureAudio(media.getPath());
                        break;
                }
            }
        }
    });
}
    private GridImageAdapter.onAddPicClickListener onAddPicClickListener = new GridImageAdapter.onAddPicClickListener() {

        @Override
        public void onAddPicClick() {

            //第一种方式,弹出选择和拍照的dialog
            showPop();
        }
    };

    private void showPop() {
        View bottomView = View.inflate(NewsMessageActivity.this, R.layout.layout_bottom_dialog, null);
        TextView mAlbum = (TextView) bottomView.findViewById(R.id.tv_album);
        TextView mCamera = (TextView) bottomView.findViewById(R.id.tv_camera);
        TextView mCancel = (TextView) bottomView.findViewById(R.id.tv_cancel);

        pop = new PopupWindow(bottomView, -1, -2);
        pop.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        pop.setOutsideTouchable(true);
        pop.setFocusable(true);
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.alpha = 0.5f;
        getWindow().setAttributes(lp);
        pop.setOnDismissListener(new PopupWindow.OnDismissListener() {

            @Override
            public void onDismiss() {
                WindowManager.LayoutParams lp = getWindow().getAttributes();
                lp.alpha = 1f;
                getWindow().setAttributes(lp);
            }
        });
        pop.setAnimationStyle(R.style.main_menu_photo_anim);
        pop.showAtLocation(getWindow().getDecorView(), Gravity.BOTTOM, 0, 0);

        View.OnClickListener clickListener = new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                switch (view.getId()) {
                    case R.id.tv_album:
                        //相册
                        PictureSelector.create(NewsMessageActivity.this)
                                .openGallery(PictureMimeType.ofImage())
                                .maxSelectNum(maxSelectNum)
                                .minSelectNum(1)
                                .imageSpanCount(4)
                                .selectionMode(PictureConfig.MULTIPLE)
                                .forResult(PictureConfig.CHOOSE_REQUEST);
                        break;
                    case R.id.tv_camera:
                        //拍照
                        PictureSelector.create(NewsMessageActivity.this)
                                .openCamera(PictureMimeType.ofImage())
                                .forResult(PictureConfig.CHOOSE_REQUEST);
                        break;
                    case R.id.tv_cancel:
                        //取消
                        break;
                }
                closePopupWindow();
            }
        };

        mAlbum.setOnClickListener(clickListener);
        mCamera.setOnClickListener(clickListener);
        mCancel.setOnClickListener(clickListener);
    }

    public void closePopupWindow() {
        if (pop != null && pop.isShowing()) {
            pop.dismiss();
            pop = null;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        List<LocalMedia> images;
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case PictureConfig.CHOOSE_REQUEST:
                    // 图片选择结果回调

                    images = PictureSelector.obtainMultipleResult(data);
                    selectList.addAll(images);
                    for (int i = 0; i < selectList.size(); i++) {
                        path = selectList.get(i).getPath();
                        files.add(new File(path));
                    }
                    adapter.setList(selectList);
                    adapter.notifyDataSetChanged();
                    break;
            }
        }
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        boolean hasPermissionDismiss = false;//有权限没有通过
        if (mRequestCode==requestCode){
            for (int i=0;i<grantResults.length;i++){
                if (grantResults[i]==-1){
                    hasPermissionDismiss=true;
                    break;
                }
            }
        }
        if (hasPermissionDismiss){//如果有没有被允许的权限
            showPermissionDialog();
        }else {
            //权限已经都通过了,可以将程序继续打开了
           initWidget();
        }

    }

    private void showPermissionDialog() {
        if (mPermissionDialog == null) {
            mPermissionDialog = new AlertDialog.Builder(this)
                    .setMessage("已禁用权限,请手动授予")
                    .setPositiveButton("设置", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            cancelPermissionDialog();
                            Uri packageURI = Uri.parse("package:" + mPackName);
                            Intent intent = new Intent(Settings.
                                    ACTION_APPLICATION_DETAILS_SETTINGS, packageURI);
                            startActivity(intent);
                        }
                    })
                    .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            //关闭页面或者做其他操作
                            cancelPermissionDialog();
                            NewsMessageActivity.this.finish();
                        }
                    })
                    .create();
        }
        mPermissionDialog.show();
    }
    private void cancelPermissionDialog() {
        mPermissionDialog.cancel();
    }

    @Override
    public void success(Object data) {
        if(data instanceof NewsReplaceBean)
        {
            NewsReplaceBean newsReplaceBean= (NewsReplaceBean) data;
            if(newsReplaceBean.getMessage().equals("发布成功"))
            {
                Toast.makeText(this, "发布成功", Toast.LENGTH_SHORT).show();
            }else
            {
                Toast.makeText(this, "发布失败", Toast.LENGTH_SHORT).show();
            }
        }
    }
    @Override
    public void failure(String error) {

    }
}

布局Recycleview



/**
 * author:luck
 * project:PictureSelector
 * package:com.luck.picture.ui
 * email:893855882@qq.com
 * data:16/12/31
 */

public class FullyGridLayoutManager extends GridLayoutManager {
    public FullyGridLayoutManager(Context context, int spanCount) {
        super(context, spanCount);
    }

    public FullyGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) {
        super(context, spanCount, orientation, reverseLayout);
    }

    private int[] mMeasuredDimension = new int[2];

    @Override
    public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) {
        final int widthMode = View.MeasureSpec.getMode(widthSpec);
        final int heightMode = View.MeasureSpec.getMode(heightSpec);
        final int widthSize = View.MeasureSpec.getSize(widthSpec);
        final int heightSize = View.MeasureSpec.getSize(heightSpec);

        int width = 0;
        int height = 0;
        int count = getItemCount();
        int span = getSpanCount();
        for (int i = 0; i < count; i++) {
            measureScrapChild(recycler, i,
                    View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
                    View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
                    mMeasuredDimension);

            if (getOrientation() == HORIZONTAL) {
                if (i % span == 0) {
                    width = width + mMeasuredDimension[0];
                }
                if (i == 0) {
                    height = mMeasuredDimension[1];
                }
            } else {
                if (i % span == 0) {
                    height = height + mMeasuredDimension[1];
                }
                if (i == 0) {
                    width = mMeasuredDimension[0];
                }
            }
        }

        switch (widthMode) {
            case View.MeasureSpec.EXACTLY:
                width = widthSize;
            case View.MeasureSpec.AT_MOST:
            case View.MeasureSpec.UNSPECIFIED:
        }

        switch (heightMode) {
            case View.MeasureSpec.EXACTLY:
                height = heightSize;
            case View.MeasureSpec.AT_MOST:
            case View.MeasureSpec.UNSPECIFIED:
        }

        setMeasuredDimension(width, height);
    }

    final RecyclerView.State mState = new RecyclerView.State();

    private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
                                   int heightSpec, int[] measuredDimension) {
        int itemCount = mState.getItemCount();
        if (position < itemCount) {
            try {
                View view = recycler.getViewForPosition(0);
                if (view != null) {
                    RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
                    int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,
                            getPaddingLeft() + getPaddingRight(), p.width);
                    int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
                            getPaddingTop() + getPaddingBottom(), p.height);
                    view.measure(childWidthSpec, childHeightSpec);
                    measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin;
                    measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin;
                    recycler.recycleView(view);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}



/**
 * author:luck
 * project:PictureSelector
 * package:com.luck.pictureselector.adapter
 * email:893855882@qq.com
 * data:16/7/27
 */
public class GridImageAdapter extends
        RecyclerView.Adapter<GridImageAdapter.ViewHolder> {
    public static final int TYPE_CAMERA = 1;
    public static final int TYPE_PICTURE = 2;
    private LayoutInflater mInflater;
    private List<LocalMedia> list = new ArrayList<>();
    private int selectMax = 9;
    private Context context;
    /**
     * 点击添加图片跳转
     */
    private onAddPicClickListener mOnAddPicClickListener;

    public interface onAddPicClickListener {
        void onAddPicClick();
    }

    public GridImageAdapter(Context context, onAddPicClickListener mOnAddPicClickListener) {
        this.context = context;
        mInflater = LayoutInflater.from(context);
        this.mOnAddPicClickListener = mOnAddPicClickListener;
    }

    public void setSelectMax(int selectMax) {
        this.selectMax = selectMax;
    }

    public void setList(List<LocalMedia> list) {
        this.list = list;
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        ImageView mImg;
        LinearLayout ll_del;
        TextView tv_duration;

        public ViewHolder(View view) {
            super(view);
            mImg = (ImageView) view.findViewById(R.id.fiv);
            ll_del = (LinearLayout) view.findViewById(R.id.ll_del);
            tv_duration = (TextView) view.findViewById(R.id.tv_duration);
        }
    }

    @Override
    public int getItemCount() {
        if (list.size() < selectMax) {
            return list.size() + 1;
        } else {
            return list.size();
        }
    }

    @Override
    public int getItemViewType(int position) {
        if (isShowAddItem(position)) {
            return TYPE_CAMERA;
        } else {
            return TYPE_PICTURE;
        }
    }

    /**
     * 创建ViewHolder
     */
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View view = mInflater.inflate(R.layout.item_filter_image,
                viewGroup, false);
        final ViewHolder viewHolder = new ViewHolder(view);
        return viewHolder;
    }

    private boolean isShowAddItem(int position) {
        int size = list.size() == 0 ? 0 : list.size();
        return position == size;
    }

    /**
     * 设置值
     */
    @Override
    public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
        //少于8张,显示继续添加的图标
        if (getItemViewType(position) == TYPE_CAMERA) {
            viewHolder.mImg.setImageResource(R.drawable.add_img);
            viewHolder.mImg.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mOnAddPicClickListener.onAddPicClick();
                }
            });
            viewHolder.ll_del.setVisibility(View.INVISIBLE);
        } else {
            viewHolder.ll_del.setVisibility(View.VISIBLE);
            viewHolder.ll_del.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    int index = viewHolder.getAdapterPosition();
                    // 这里有时会返回-1造成数据下标越界,具体可参考getAdapterPosition()源码,
                    // 通过源码分析应该是bindViewHolder()暂未绘制完成导致,知道原因的也可联系我~感谢
                    if (index != RecyclerView.NO_POSITION) {
                        list.remove(index);
                        notifyItemRemoved(index);
                        notifyItemRangeChanged(index, list.size());
                        DebugUtil.i("delete position:", index + "--->remove after:" + list.size());
                    }
                }
            });
            LocalMedia media = list.get(position);
            int mimeType = media.getMimeType();
            String path = "";
            if (media.isCut() && !media.isCompressed()) {
                // 裁剪过
                path = media.getCutPath();
            } else if (media.isCompressed() || (media.isCut() && media.isCompressed())) {
                // 压缩过,或者裁剪同时压缩过,以最终压缩过图片为准
                path = media.getCompressPath();
            } else {
                // 原图
                path = media.getPath();
            }
            // 图片
            if (media.isCompressed()) {
                Log.i("compress image result:", new File(media.getCompressPath()).length() / 1024 + "k");
                Log.i("压缩地址::", media.getCompressPath());
            }

            Log.i("原图地址::", media.getPath());
            int pictureType = PictureMimeType.isPictureType(media.getPictureType());
            if (media.isCut()) {
                Log.i("裁剪地址::", media.getCutPath());
            }
            long duration = media.getDuration();
            viewHolder.tv_duration.setVisibility(pictureType == PictureConfig.TYPE_VIDEO
                    ? View.VISIBLE : View.GONE);
            if (mimeType == PictureMimeType.ofAudio()) {
                viewHolder.tv_duration.setVisibility(View.VISIBLE);
                Drawable drawable = ContextCompat.getDrawable(context, R.drawable.picture_audio);
                StringUtils.modifyTextViewDrawable(viewHolder.tv_duration, drawable, 0);
            } else {
                Drawable drawable = ContextCompat.getDrawable(context, R.drawable.video_icon);
                StringUtils.modifyTextViewDrawable(viewHolder.tv_duration, drawable, 0);
            }
            viewHolder.tv_duration.setText(DateUtils.timeParse(duration));
            if (mimeType == PictureMimeType.ofAudio()) {
                viewHolder.mImg.setImageResource(R.drawable.audio_placeholder);
            } else {
                RequestOptions options = new RequestOptions()
                        .centerCrop()
                        .placeholder(R.color.color_4d)
                        .diskCacheStrategy(DiskCacheStrategy.ALL);
                Glide.with(viewHolder.itemView.getContext())
                        .load(path)
                        .apply(options)
                        .into(viewHolder.mImg);
            }
            //itemView 的点击事件
            if (mItemClickListener != null) {
                viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        int adapterPosition = viewHolder.getAdapterPosition();
                        mItemClickListener.onItemClick(adapterPosition, v);
                    }
                });
            }
        }
    }

    protected OnItemClickListener mItemClickListener;

    public interface OnItemClickListener {
        void onItemClick(int position, View v);
    }

    public void setOnItemClickListener(OnItemClickListener listener) {
        this.mItemClickListener = listener;
    }
}

item_filter_image

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

    <RelativeLayout
        android:layout_width="90dp"
        android:layout_height="90dp"
        android:layout_centerInParent="true">

        <ImageView
            android:id="@+id/fiv"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:layout_marginTop="10dp"
            android:contentDescription="@null"
            android:scaleType="centerCrop"
            android:src="@color/color_f6"/>

        <LinearLayout
            android:id="@+id/ll_del"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:gravity="end"
            android:orientation="vertical">

            <ImageView
                android:id="@+id/iv_del"
                android:layout_width="25dp"
                android:layout_height="25dp"
                android:contentDescription="@null"
                android:scaleType="fitXY"
                android:src="@drawable/delete"/>

        </LinearLayout>

        <TextView
            android:id="@+id/tv_duration"
            android:layout_width="80dp"
            android:layout_height="30dp"
            android:layout_alignParentBottom="true"
            android:layout_marginBottom="5dp"
            android:background="@drawable/buybuybuy"
            android:drawableLeft="@drawable/video_icon"
            android:drawablePadding="5dp"
            android:gravity="center_vertical"
            android:paddingLeft="5dp"
            android:paddingTop="8dp"
            android:text="00:00"
            android:textColor="@color/white"
            android:textSize="12sp"
            android:visibility="gone"/>

    </RelativeLayout>

</RelativeLayout>

layout_bottom_dialog

<?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"
              android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tv_album"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/shape_album"
            android:gravity="center"
            android:padding="15dp"
            android:text="相册"
            android:textSize="16sp"/>

        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="#f5f5f5"/>

        <TextView
            android:id="@+id/tv_camera"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/shape_camera"
            android:gravity="center"
            android:padding="15dp"
            android:text="拍照"
            android:textSize="16sp"/>

        <TextView
            android:id="@+id/tv_cancel"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:background="@drawable/shape_cancel"
            android:gravity="center"
            android:padding="15dp"
            android:text="取消"
            android:textSize="16sp"/>

    </LinearLayout>

</LinearLayout>

anim

photo_dialog_in_anim

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="200"
        android:fromXDelta="0"
        android:fromYDelta="1000"
        android:toXDelta="0"
        android:toYDelta="0" />

</set>
photo_dialog_out_anim


<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="300"
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="0"
        android:toYDelta="1000" />

</set>

Stytle
 <style name="main_menu_photo_anim">
        <item name="android:windowEnterAnimation">@anim/photo_dialog_in_anim</item>
        <item name="android:windowExitAnimation">@anim/photo_dialog_out_anim</item>
    </style>

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Android 中使用 Retrofit 上传图片可以通过 `@Multipart` 和 `@Part` 注解实现。以下是 Retrofit 2.0 实现图文上传的方法总结: 1. 添加依赖库 在项目的 `build.gradle` 文件中添加以下依赖库: ```groovy implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.squareup.retrofit2:converter-scalars:2.9.0' ``` 2. 创建 Retrofit 实例 ```java Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); ``` 3. 创建 API 接口 ```java public interface ApiService { @Multipart @POST("upload") Call<ResponseBody> upload( @Part("description") RequestBody description, @Part MultipartBody.Part file); } ``` 其中,`@Multipart` 注解表示这是一个包含文本和文件的表单;`@POST("upload")` 表示上传的 URL 地址;`@Part("description") RequestBody description` 表示上传的文本参数,`description` 是参数名,可以自己定义;`@Part MultipartBody.Part file` 表示上传的文件参数。 4. 创建请求参数 ```java File file = new File(filePath); RequestBody requestFile = RequestBody.create(MediaType.parse("image/*"), file); MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), requestFile); RequestBody description = RequestBody.create(MediaType.parse("multipart/form-data"), "description"); ``` 5. 发送网络请求 ```java ApiService apiService = retrofit.create(ApiService.class); Call<ResponseBody> call = apiService.upload(description, body); call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { // 成功上传后的处理 } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { // 上传失败后的处理 } }); ``` 以上就是 Retrofit 2.0 实现图文上传的方法总结。注意,在 `AndroidManifest.xml` 文件中需要添加网络权限: ```xml <uses-permission android:name="android.permission.INTERNET" /> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值