模仿微信朋友圈发布动态,输入文字支持文字多少高度自增,有一个最小输入框高度,输入文字有限制,不过这些都很easy!

1. PhotoPicker的使用

这是一个支持选择多张图片,点击图片放大,图片之间左右滑动互相切换的库,同时支持图片删除的库,效果类似微信。

(1) 添加PhotoPicker的架包

(2) 使用

    选择图片:安卓6.0以后需要在代码中添加读写sd卡和相机的权限 当然清单文件中也需要添加的
    PhotoPicker.builder()
                .setPhotoCount(maxPhoto) //设置最多选择的图片数量
                .setShowCamera(true)    //是否显示相机按钮
                .setSelected(photos)    //设置已经选好的图片
                .start(SendDynamicActivity.this); //上下文参数 需要传activity

    查看图片:
    PhotoPreview.builder()
                .setPhotos(photos)  //设置选择好的图片
                .setCurrentItem(position) //设置当前选择的条目
                .setShowDeleteButton(true)  //是否显示删除按钮
                .start(this);

2. 发布朋友圈页面

代码比较简单直接上

package com.zlc.friendcirclephoto.ui;

import android.Manifest;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.text.InputFilter;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.mylhyl.acp.Acp;
import com.mylhyl.acp.AcpListener;
import com.mylhyl.acp.AcpOptions;
import com.zlc.friendcirclephoto.adapter.MyItemTouchHelperCallback;
import com.zlc.friendcirclephoto.adapter.SendImageAdapter;
import com.zlc.friendcirclephoto.view.CommonEditText;
import com.zlc.friendcirclephoto.R;
import com.zlc.friendcirclephoto.utils.LogUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import me.iwf.photopicker.PhotoPicker;
import me.iwf.photopicker.PhotoPreview;

/**
 * Created by zlc
 * 发布朋友圈
 */
public class SendDynamicActivity extends BaseActivity implements View.OnClickListener,SendImageAdapter.OnClickListener{

    private ImageView im_fanhui;
    private TextView tv_title;
    private CommonEditText id_et_content;
    private TextView id_tv_num;
    private TextView id_tv_max_num;
    private SendImageAdapter mPhotoAdapter;
    public static final int maxPhoto = 9; //最大选择几张照片
    private List<Object> images = new ArrayList<>();
    private ArrayList<String> photos = new ArrayList<>();
    private RecyclerView mRecycleView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_send_note);
        initView();
        initData();
        initListener();
    }

    private void initView() {

        im_fanhui = findView(R.id.id_iv_back);
        tv_title = findView(R.id.id_tv_title);
        tv_title.setText("发布");
        id_et_content = findView(R.id.id_common_et);
        mRecycleView = findView(R.id.id_recycleview);
        id_tv_num = findView(R.id.tv_num);
        id_tv_max_num = findView(R.id.id_tv_max_num);
        id_et_content.setHint("这一刻的想法......");
        id_tv_num.setText("0");
        id_tv_max_num.setText("/188");
        id_et_content.setFilters(new InputFilter[]{new InputFilter.LengthFilter(188)});
    }


    private void initData() {
        images.add(1);
        mRecycleView.setLayoutManager(new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL));
        mPhotoAdapter = new SendImageAdapter(SendDynamicActivity.this, images);
        mRecycleView.setAdapter(mPhotoAdapter);
        mPhotoAdapter.setOnClickListener(this);
        MyItemTouchHelperCallback callBack = new MyItemTouchHelperCallback(mPhotoAdapter);
        //实现拖拽排序
        final ItemTouchHelper touchHelper = new ItemTouchHelper(callBack);
        //调用ItemTouchHelper的attachToRecyclerView方法建立联系
        touchHelper.attachToRecyclerView(mRecycleView);
    }

    private void initListener() {
        im_fanhui.setOnClickListener(this);
        id_et_content.setOnTextChaged(new CommonEditText.OnTextChaged() {
            @Override
            public void setText(String s) {
                id_tv_num.setText(s.length()+"");
            }
        });
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.id_iv_back:
                finish();
                break;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK && (requestCode == PhotoPicker.REQUEST_CODE || requestCode == PhotoPreview.REQUEST_CODE)) {
            List<String> photos = null;
            if (data != null) {
                photos = data.getStringArrayListExtra(PhotoPicker.KEY_SELECTED_PHOTOS);
            }
            if (photos != null) {
                clearPhotoS(photos.size());
                images.addAll(images.size()-1,photos);
                mPhotoAdapter.notifyDataSetChanged();
            }
        }

    }

    @Override
    public void onClick(View v, int position) {
        switch (v.getId()){
            case R.id.iv_add:
                selectPhoto();
                break;
            case R.id.im_delete:
                delImages(position);
                break;
            case R.id.iv_img:
                lookPhoto(position);
                break;
        }
    }

    public void delImages(int position){
        images.remove(position);
        if(mPhotoAdapter!=null)
            mPhotoAdapter.notifyItemRemoved(position);
    }

    public void  clearPhotoS(int size){
        LogUtil.e("返回有几张照片",size+"");
        images.clear();
        images.add(1);
    }

    //选择图片
    private void selectPhoto() {

        List<Object> images = mPhotoAdapter.getDatas();
        photos.clear();
        for (int i = 0;i< images.size()-1;i++ ){
            photos.add(images.get(i).toString());
        }
        //权限
        Acp.getInstance(this).request(new AcpOptions.Builder()
                        .setPermissions(
                                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                                Manifest.permission.CAMERA,
                                Manifest.permission.READ_EXTERNAL_STORAGE
                        )
                        .build(),
                new AcpListener() {
                    @Override
                    public void onGranted() {
                        LogUtil.e("msg", "权限外全部通过");
                        PhotoPicker.builder()
                                .setPhotoCount(maxPhoto)
                                .setShowCamera(true)
                                .setSelected(photos)
                                .start(SendDynamicActivity.this);
                    }
                    @Override
                    public void onDenied(List<String> permissions) {
                        LogUtil.e(permissions.toString() ,"权限拒绝");
                    }
                });
    }

    //查看图片
    private void lookPhoto(int position){
        photos.clear();
        List<Object> images = mPhotoAdapter.getDatas();
        for (int i = 0;i< images.size()-1;i++ ){
            photos.add(images.get(i).toString());
        }
        PhotoPreview.builder()
                .setPhotos(photos)
                .setCurrentItem(position)
                .setShowDeleteButton(true)  //是否显示删除按钮
                .start(this);
    }
}

3. 图片适配器代码

public class SendImageAdapter extends RecyclerView.Adapter<SendImageAdapter.ViewHolder> implements ItemTouchHelperAdapter{

    private Activity mContext;
    private List<Object> mDatas;
    private LayoutInflater mLayoutInflater;
    public SendImageAdapter(Activity context,List<Object> datas){
        this.mContext = context;
        this.mDatas = datas;
        mLayoutInflater = LayoutInflater.from(context);
    }

    @Override
    public SendImageAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View  view = mLayoutInflater.inflate(R.layout.send_grid_item,parent,false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(final SendImageAdapter.ViewHolder viewHolder, final int position) {

        Object image = mDatas.get(position);
        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) viewHolder.id_rl_img.getLayoutParams();
        int w = params.width = (int) ((ScreenUtil.getScreenWidth(mContext) - DensityUtil.dp2px(mContext,38)) / 3.0);
        params.height = w;
        params.bottomMargin = DensityUtil.dp2px(mContext,7);
        params.rightMargin = DensityUtil.dp2px(mContext,7);
        viewHolder.id_rl_img.setLayoutParams(params);

        if (image instanceof String) {
            viewHolder.im_delete.setVisibility(View.VISIBLE);
            viewHolder.iv_add.setVisibility(View.GONE);
            viewHolder.im_img.setVisibility(View.VISIBLE);
            //这里最好使用glide Picasso加载本地图片 bitmap容易造成内存溢出
            Bitmap bitmap = BitmapFactory.decodeFile(image.toString());
            viewHolder.im_img.setImageBitmap(bitmap);
            LogUtil.e("手机照片", image.toString());
        } else {
            viewHolder.im_delete.setVisibility(View.INVISIBLE);
            viewHolder.iv_add.setVisibility(View.VISIBLE);
            viewHolder.im_img.setVisibility(View.GONE);
            viewHolder.iv_add.setImageResource(R.drawable.tupiantianjia2x);
            LogUtil.e("添加照片", ""+image);
        }
        viewHolder.iv_add.setOnClickListener(new MyClickListener(viewHolder));
        viewHolder.im_img.setOnClickListener(new MyClickListener(viewHolder));
        viewHolder.im_delete.setOnClickListener(new MyClickListener(viewHolder));
    }

    @Override
    public int getItemCount() {
        if(mDatas == null){
            return 0;
        }
        return mDatas.size() >= 9 ? 9 : mDatas.size();
    }

    public List<Object> getDatas() {
        return mDatas;
    }

    public static class ViewHolder extends RecyclerView.ViewHolder{

        private final ImageView im_img;
        private final ImageView iv_add;
        private final ImageView im_delete;
        private final FrameLayout id_rl_img;

        public ViewHolder(View itemView) {
            super(itemView);
            im_img = (ImageView) itemView.findViewById(R.id.iv_img);
            iv_add = (ImageView) itemView.findViewById(R.id.iv_add);
            im_delete = (ImageView) itemView.findViewById(R.id.im_delete);
            id_rl_img = (FrameLayout) itemView.findViewById(R.id.id_rl_img);
        }
    }

    //拖拽排序相关
    @Override
    public void onItemMove(int fromPos, int toPos) {
        if(fromPos == mDatas.size()-1 || toPos == mDatas.size()-1 )
            return;
        if (fromPos < toPos)
            //向下拖动
            for (int i = fromPos; i < toPos; i++) {
                Collections.swap(mDatas, i, i + 1);
            }
        else {
            //向上拖动
            for (int i = fromPos; i > toPos; i--) {
                Collections.swap(mDatas, i, i - 1);
            }
        }
        notifyItemMoved(fromPos,toPos);
    }

    //滑动删除相关
    @Override
    public void onItemDel(int pos) {
        if(pos == mDatas.size() - 1)
            return;
        mDatas.remove(pos);
        notifyItemRemoved(pos);
    }


    public interface OnClickListener{
        void onClick(View v, int position);
    }

    private static OnClickListener onClickListener;

    public void setOnClickListener(OnClickListener onClickListener) {
        this.onClickListener = onClickListener;
    }

    public static class MyClickListener implements View.OnClickListener{

        private ViewHolder mHolder;
        public MyClickListener(ViewHolder holder ){
            this.mHolder = holder;
        }

        @Override
        public void onClick(View view) {
            switch (view.getId()){
                case R.id.iv_add:
                case R.id.im_delete:
                case R.id.iv_img:
                    if(onClickListener!=null) {
                        int pos = mHolder.getAdapterPosition();
                        onClickListener.onClick(view, pos);
                    }
                    break;
            }
        }
    }
}

4. 拖拽排序

(1) RecycleView通过ItemTouchHelper 实现
    MyItemTouchHelperCallback callBack = new   MyItemTouchHelperCallback(mPhotoAdapter);
    //实现拖拽排序
    final ItemTouchHelper touchHelper = new ItemTouchHelper(callBack);
    //调用ItemTouchHelper的attachToRecyclerView方法建立联系
    touchHelper.attachToRecyclerView(mRecycleView);

(2) MyItemTouchHelperCallback的自定义
package com.zlc.friendcirclephoto.adapter;

import android.graphics.Canvas;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.support.v7.widget.helper.ItemTouchHelper;

public class MyItemTouchHelperCallback extends ItemTouchHelper.Callback {

    private SendImageAdapter mAdapter;  //适配器传过来
    private boolean isLongDrag = true;
    private boolean isMoveSwipe = true;

    public MyItemTouchHelperCallback(SendImageAdapter adapter){
        this.mAdapter = adapter;
    }

    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {

        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        int dragFlags = 0;  //拖拽的标志
        int swipeFlags = 0; //删除的标志
        int position = viewHolder.getAdapterPosition();
        if(position == mAdapter.getDatas().size() - 1){  // 如果是最后一个条目 则既不能拖拽也不能删除
            dragFlags = 0;
            swipeFlags = 0;
        } else if(layoutManager instanceof GridLayoutManager || layoutManager instanceof StaggeredGridLayoutManager){//网格布局 则支持上下左右拖拽 不支持删除
            dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;  //允许上下左右的拖动
            swipeFlags  = 0;  //不能删除
        }else if(layoutManager instanceof LinearLayoutManager){  //线性布局分为垂直和水平

            LinearLayoutManager manager = (LinearLayoutManager) layoutManager;
            int orientation = manager.getOrientation();
            if(orientation == LinearLayoutManager.HORIZONTAL){  //横向listview列表 

                dragFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;  //允许左右的拖动
                swipeFlags  = ItemTouchHelper.DOWN;  //只允许从上向下侧滑

            }else if(orientation == LinearLayoutManager.VERTICAL){  //竖向listview列表

                dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;  //允许上下的拖动
                swipeFlags  = ItemTouchHelper.LEFT;  //只允许从右向左侧滑删除
            }

        }else{   //最后一个条目既不能拖拽也不能删除 相当于更多
            dragFlags = 0;
            swipeFlags = 0;
        }
        return makeMovementFlags(dragFlags,swipeFlags);
    }

    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        mAdapter.onItemMove(viewHolder.getAdapterPosition(),target.getAdapterPosition());
        return true;
    }

    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
        mAdapter.onItemDel(viewHolder.getAdapterPosition());
    }

   // 该方法返回true时,表示支持长按拖动
    @Override
    public boolean isLongPressDragEnabled() {
        return isLongDrag;
    }

    //该方法返回true时,表示支持滑动删除
    @Override
    public boolean isItemViewSwipeEnabled() {
        return isMoveSwipe;
    }

    //从静止状态变为拖拽或者滑动的时候会回调该方法,参数actionState表示当前的状态。 开始拖拽的时候给item添加一个背景色,然后在拖拽完成的时候还原
    @Override
    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
        //拖拽的时候才设置背景颜色
//        if (actionState != ItemTouchHelper.ACTION_STATE_IDLE && actionState != ItemTouchHelper.ACTION_STATE_SWIPE) {
//            viewHolder.itemView.setBackgroundColor(Color.LTGRAY);
//        }
        super.onSelectedChanged(viewHolder, actionState);
    }

    //当用户操作完毕某个item并且其动画也结束后会调用该方法
    @Override
    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        //重置改变,防止由于复用而导致的显示问题
        super.clearView(recyclerView, viewHolder);
        viewHolder.itemView.setBackgroundColor(0);
    }

    //我们可以在这个方法内实现我们自定义的交互规则或者自定义的动画效果
    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
    }

    public void setLongDrag(boolean longDrag) {
        isLongDrag = longDrag;
    }

    public void setMoveSwipe(boolean moveSwipe) {
        isMoveSwipe = moveSwipe;
    }
}

(3) 具体实现方法

    //拖拽排序相关
    @Override
    public void onItemMove(int fromPos, int toPos) {
        if(fromPos == mDatas.size()-1 || toPos == mDatas.size()-1 )
            return;
        if (fromPos < toPos)
            //向下拖动
            for (int i = fromPos; i < toPos; i++) {
                Collections.swap(mDatas, i, i + 1);
            }
        else {
            //向上拖动
            for (int i = fromPos; i > toPos; i--) {
                Collections.swap(mDatas, i, i - 1);
            }
        }
        notifyItemMoved(fromPos,toPos);
    }

    //滑动删除相关
    @Override
    public void onItemDel(int pos) {
        if(pos == mDatas.size() - 1)
            return;
        mDatas.remove(pos);
        notifyItemRemoved(pos);
    }