Android 高仿微信朋友圈拍照上传功能
作者:尽人事看天意
这篇文章主要介绍了Android 高仿微信朋友圈拍照上传功能,需要的朋友可以参考下
模仿微信朋友圈发布动态,输入文字支持文字多少高度自增,有一个最小输入框高度,输入文字有限制,不过这些都很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; Collections.swap(mDatas,fromPos,toPos); 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; Collections.swap(mDatas,fromPos,toPos); notifyItemMoved(fromPos,toPos); } //滑动删除相关 @Override public void onItemDel(int pos) { if(pos == mDatas.size() - 1) return; mDatas.remove(pos); notifyItemRemoved(pos); }
5. 联系方式
qq:1509815887@qq.com
email : zlc921022@163.com
phone : 18684732678
总结
以上所述是小编给大家介绍的Android 高仿微信朋友圈拍照上传功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!