Skip to content

Commit

Permalink
docs(0.9.3): 增加代码注释,修改README
Browse files Browse the repository at this point in the history
  • Loading branch information
free46000 committed Apr 4, 2017
1 parent b476da2 commit ef2f027
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 49 deletions.
16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,18 @@
`MutliItem`主要就是解决这些问题,在正常使用中做到了`Adapter`零编码,解放了复杂的`Adapter`类,本库提供了多类型和`ViewHolder`创建绑定的管理器,这样`Adapter`通过依赖倒置与列表中的多类型解耦,还提高了扩展性。在本库中不同实体类可以直接当成数据源绑定到`adapter`中,你不用去担心`item type`的计算,并且对每种类型的`ViewHolder`也做到了隔离。
本库的定位并不是大而全,但是会尽量做到简单易用。

## 效果截图
![multi_item](https://github.com/free46000/cloud/raw/master/multiitem/multi_item.png )![chat](https://github.com/free46000/cloud/raw/master/multiitem/chat.png)
## 系列文章
- 用法与详解(详见下文)

![multi_item](https://github.com/free46000/cloud/raw/master/multiitem/multi_item.png )
![chat](https://github.com/free46000/cloud/raw/master/multiitem/chat.png)
- [MultiItem进阶 实现Head Foot和加载更多](https://juejin.im/post/58da77ed1b69e6006bc7fffa)

![headfoot](https://user-gold-cdn.xitu.io/2017/3/29/1846a3cd1a81b9b0bb516402d1cee6aa.png )
![fullspan](https://user-gold-cdn.xitu.io/2017/3/29/59b465977da7c11b455a9998143e5e2a.png )
![loadmore](https://user-gold-cdn.xitu.io/2017/3/29/7b50786340f253d2f8e5f7966cfd7fc1.png )

## 下一步要做什么
- 任务面板 跨`RecyclerView``Item`拖动 支持双击缩小后拖动(仿协同办公软件)
- 增加`header footer line`等一些可复用视图
- DataBinding特性支持
- 录入界面的复用和封装的demo代码(录入业务较多同学可以多多关注)
- 思考动画分割线等一些功能封装
Expand All @@ -29,7 +35,7 @@ allprojects {
`Module`中添加:
```
dependencies {
compile 'com.github.free46000:MultiItem:0.9.1'
compile 'com.github.free46000:MultiItem:0.9.3'
}
```

Expand Down
27 changes: 10 additions & 17 deletions demo/src/main/java/com/freelib/multiitem/demo/PanelActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,27 @@ public static void startActivity(Context context) {

@AfterViews
protected void initView() {
setTitle(R.string.panel_title);

horizontalRecycler = (RecyclerView) findViewById(R.id.recyclerView);

adapter = new BaseItemAdapter();
//此处不能复用,所以使用ItemUnique保证唯一,Item可以动态匹配ViewHolderManager所以不用注册
//此处为了简单所以使用不可复用的模式,正式业务视具体情况而定!!!
adapter.addDataItems(Arrays.asList(new UniqueItemManager(new RecyclerViewManager(15)),
new UniqueItemManager(new RecyclerViewManager(1)), new UniqueItemManager(new RecyclerViewManager(25)),
new UniqueItemManager(new RecyclerViewManager(15)), new UniqueItemManager(new RecyclerViewManager(5))));
//设置横向滚动LinearLayoutManager
horizontalRecycler.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
horizontalRecycler.setAdapter(adapter);

//ItemDragHelper,需要传入外层的横向滚动的RecyclerView
dragHelper = new ItemDragHelper(horizontalRecycler);
dragHelper.setOnItemDragListener(new OnBaseDragListener());

scaleHelper = new ViewScaleHelper();
//设置最外层的Content视图
scaleHelper.setContentView(contentView);
//设置横向的Recycler列表视图
scaleHelper.setHorizontalView(horizontalRecycler);

//监听横向滚动RecyclerView双击事件,并开启关闭缩放模式
Expand Down Expand Up @@ -122,7 +129,7 @@ protected void onCreateViewHolder(@NonNull BaseViewHolder holder) {

recyclerView.setLayoutManager(new LinearLayoutManager(view.getContext()));
final BaseItemAdapter baseItemAdapter = new BaseItemAdapter();
//为XXBean数据源注册Xager管理类
//为XXBean数据源注册XXHolderManager管理类 数据源必须实现ItemData接口
baseItemAdapter.register(TextDragBean.class, new TextViewDragManager());
baseItemAdapter.register(ImageTextBean.class, new ImageAndTextManager());
baseItemAdapter.setDataItems(getItemList(length));
Expand All @@ -131,11 +138,8 @@ protected void onCreateViewHolder(@NonNull BaseViewHolder holder) {
baseItemAdapter.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
protected void onItemLongClick(BaseViewHolder viewHolder) {
dragHelper.setOnItemDragListener(new OnBaseDragListener());
dragHelper.startDrag(viewHolder);
}


});
}

Expand Down Expand Up @@ -166,7 +170,7 @@ private List<Object> getItemList(int length) {
}

private String getText(int index, int length) {
String text = "事项:\n不可被切换Recycler" + index;
String text = "事项:\n不可被切换RecyclerView==" + index;
if (!isCanDragMove(index, length)) {
text += "\n不可以被拖动\n不可以被移动";
}
Expand All @@ -177,17 +181,6 @@ private String getText(int index, int length) {
private boolean isCanDragMove(int index, int length) {
return index != 0 || length < 10;
}
// private List<Object> getItemList(int length) {
// List<Object> list = new ArrayList<>();
// for (int i = 0; i < length; i++) {
// if (i == 1) {
// list.add(new TextDragBean(i + "标题\n内容A\n内容B\n内容C" + i));
// }
// String content = String.format("事项:%s\n事项内容:%s%s", i, i, i > 9 ? "\n更多内容" : "");
// list.add(i % 2 == 1 ? new ImageTextBean(R.drawable.img2, content) : new TextDragBean(content));
// }
// return list;
// }

}
}
16 changes: 5 additions & 11 deletions demo/src/main/res/layout/item_recycler_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,11 @@
android:textSize="16dp"
tools:text="测试标题"/>

<RelativeLayout android:layout_below="@+id/item_group_name"
<android.support.v7.widget.RecyclerView
android:id="@+id/item_group_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.v7.widget.RecyclerView
android:id="@+id/item_group_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"

android:paddingLeft="8dp"
android:paddingRight="8dp"/>
</RelativeLayout>
android:layout_height="wrap_content"

android:paddingLeft="8dp"
android:paddingRight="8dp"/>
</RelativeLayout>
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ public void onBindViewHolder(BaseViewHolder holder, int position) {
public int getItemViewType(int position) {
int type = itemTypeManager.getItemType(getItem(position));
if (type < 0)
throw new RuntimeException("没有为" + getItem(position).getClass() + "找到对应的item itemView provider,是否注册了?");
throw new RuntimeException("没有为" + getItem(position).getClass() + "找到对应的item itemView manager,是否注册了?");
return type;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

/**
* 拖动时浮动Item视图辅助类
* 浮动视图采用WindowManager + ImageView展示被拖动Item视图生成的Bitmap
* Created by free46000 on 2017/4/1.
*/
public class DragFloatViewHelper {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.freelib.multiitem.helper;

import android.support.annotation.NonNull;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.OrientationHelper;
Expand All @@ -17,13 +18,25 @@
* Created by free46000 on 2016/8/19.
* 面板拖动辅助类 -跨RecyclerView拖动
* <p>
* todo 注释要详细 完整流程的解读,各项数据计算最好带上 在readme中添加uml流程图(plantuml)
* <b>计算横向和竖向的RecyclerView滚动</b>{@link #scrollIfNecessary(RecyclerView, int, int)}<br>
* 大量参考了`ItemTouchHelper`的源码,根据用户触摸位置计算是否需要滚动,和滚动的方向与距离 详见ItemDragListener的calcXXXScrollDistance() calcScrollXXXDirect();
* 采用定时Runnable形式,保证持续的滚动;
* 滚动时调用Item位置计算方法,使得在滚动过程中也可以更换Item位置
* <p>
* <b>Item位置更换计算</b>{@link #moveIfNecessary(float, float)}<br>
* 触摸位置都为相对屏幕位置,方便后续计算
* 根据触摸位置horizontalRecycler.findChildViewUnder(x, y)找到垂直recyclerView的位置,若找到位置继续<br>
* 根据上一次垂直recyclerView所在的位置,判断是否为第一次选中或者是切换recyclerView的操作,此处可通过itemDragListener回调拦截此次操作的结果<br>
* 如果需要切换recyclerView的位置,此时需要对被拖动的Item进行remove,并在新的recyclerView中add进去<br>
* 根据触摸位置recyclerView.findChildViewUnder(itemX, itemY)找到itemView的位置<br>
* 根据上一次itemView所在的位置,判断是否需要移动itemView位置的操作,此处可通过itemDragListener回调拦截此次操作的结果<br>
* 如果需要移动动itemView位置则需要把recyclerView滚动到合适的位置,防recyclerView乱跳<br>
*/
public class ItemDragHelper {
public static final int NONE = -1;

private OnItemDragListener dragListener = new EmptyDragListener();
private RecyclerView horizontalRecycler;
private OnItemDragListener dragListener;
private DragFloatViewHelper floatViewHelper;
private boolean isDrag;

Expand All @@ -38,7 +51,7 @@ public class ItemDragHelper {
*
* @param horizontalRecycler
*/
public ItemDragHelper(RecyclerView horizontalRecycler) {
public ItemDragHelper(@NonNull RecyclerView horizontalRecycler) {
this.horizontalRecycler = horizontalRecycler;
floatViewHelper = new DragFloatViewHelper();
}
Expand All @@ -48,7 +61,7 @@ public ItemDragHelper(RecyclerView horizontalRecycler) {
*
* @param viewHolder 选中的Item的ViewHolder
*/
public void startDrag(BaseViewHolder viewHolder) {
public void startDrag(@NonNull BaseViewHolder viewHolder) {
View itemView = viewHolder.itemView;
int itemPosition = viewHolder.getItemPosition();
dragListener.setItemViewHolder(viewHolder);
Expand Down Expand Up @@ -79,7 +92,7 @@ private void initParams() {
*
* @param onItemDragListener 回调Listener
*/
public void setOnItemDragListener(OnItemDragListener onItemDragListener) {
public void setOnItemDragListener(@NonNull OnItemDragListener onItemDragListener) {
this.dragListener = onItemDragListener;
}

Expand All @@ -93,7 +106,7 @@ public RecyclerView getHorizontalRecycler() {
* @param event touch的event
* @return true表示消耗掉事件
*/
public boolean onTouch(MotionEvent event) {
public boolean onTouch(@NonNull MotionEvent event) {
lastTouchRawX = event.getRawX();
lastTouchRawY = event.getRawY();

Expand All @@ -118,8 +131,8 @@ public boolean onTouch(MotionEvent event) {

private void scrollRunnableStart() {
if (lastRecyclerView != null) {
lastRecyclerView.removeCallbacks(mScrollRunnable);
mScrollRunnable.run();
lastRecyclerView.removeCallbacks(scrollRunnable);
scrollRunnable.run();
lastRecyclerView.invalidate();
}
}
Expand Down Expand Up @@ -150,7 +163,7 @@ private boolean moveIfNecessary(float touchRawX, float touchRawY) {
// System.out.println("find_parent_out:lastRecyclerPos:" + lastRecyclerPos + "-recyclerPos:" + recyclerPos + "==location[0]:" + location[0] + "==location[1]:" + location[1]);
RecyclerView recyclerView = findRecyclerView(view);

//没有找到所属位置或者目标RecyclerView,则不移动
//没有找到所属位置或者目标RecyclerView,则不继续
if (recyclerPos == NONE || recyclerView == null) {
return false;
}
Expand Down Expand Up @@ -299,7 +312,7 @@ protected RecyclerView findRecyclerView(View view) {
/**
* 滚动Runnable,为了可持续滚动
*/
private final Runnable mScrollRunnable = new Runnable() {
private final Runnable scrollRunnable = new Runnable() {

@Override
public void run() {
Expand All @@ -310,7 +323,7 @@ public void run() {
if (isDrag && (isHorizontalScroll || isVerticalScroll)) {
//it might be lost during scrolling
moveIfNecessary(lastTouchRawX, lastTouchRawY);
lastRecyclerView.removeCallbacks(mScrollRunnable);
lastRecyclerView.removeCallbacks(scrollRunnable);
ViewCompat.postOnAnimation(lastRecyclerView, this);
}
}
Expand Down Expand Up @@ -429,4 +442,8 @@ private boolean isSelectedRecyclerView(int lastRecyclerPos, int currRecyclerPos)
private boolean isSelectedChildView(int lastChildPos, int currChildPos) {
return lastChildPos == NONE && currChildPos != NONE;
}

static class EmptyDragListener extends OnItemDragListener {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -219,14 +219,14 @@ public int onItemChangedPosition(RecyclerView recyclerView, int fromPos, int toP
* @return 最大水平滚动速度
*/
public int getHorizontalScrollMaxSpeed() {
return (int) (horizontalScrollMaxSpeed * getScale());
return (int) (horizontalScrollMaxSpeed / getScale());
}

/**
* @return 最大垂直滚动速度
*/
public int getVerticalScrollMaxSpeed() {
return (int) (verticalScrollMaxSpeed * getScale());
return (int) (verticalScrollMaxSpeed / getScale());
}

/**
Expand All @@ -235,7 +235,7 @@ public int getVerticalScrollMaxSpeed() {
* @return 水平滚动临界范围
*/
public float getHorizontalLimit() {
return horizontalLimit * getScale();
return horizontalLimit / getScale();
}

/**
Expand All @@ -244,7 +244,7 @@ public float getHorizontalLimit() {
* @return 垂直滚动临界范围
*/
public float getVerticalLimit() {
return verticalLimit * getScale();
return verticalLimit / getScale();
}

/**
Expand Down Expand Up @@ -339,6 +339,12 @@ public void onDrawFloatView(View floatView) {
floatView.setAlpha(0.8f);
}

/**
* 当touch位置在目标视图高度的边界值时对两个Item进行move的处理
* 默认0.5即超过一半高度时允许两个Item move
*
* @return 两个Item是否进行move边界值
*/
public float getMoveLimit() {
return 0.5f;
}
Expand Down

0 comments on commit ef2f027

Please sign in to comment.