模仿微信朋友圈發佈動態,輸入文字支持文字多少高度自增,有一個最小輸入框高度,輸入文字有限制,不過這些都很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);
}
5. 聯繫方式
qq:1509815887@qq.com
email : zlc921022@163.com
phone : 18684732678
6.下載地址
點擊去下載