目录
一、设计思路
①、自定义一个组件,加载一个内含Head、ListContainer、Foot的布局文件。
②、监听此布局的触摸事件
③、监听ListContainer是否滑动到顶部或者底部。
④、根据②和③监听事件做相应的显示和隐藏(head、foot)布局即可。
二、动手实现
1、新建类RefreshListContainer继承ComponentContainer
2、新建包含Head、ListContainer、Foot布局文件,refresh_layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<DependentLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:background_element="$color:dialog_btn_gray_color"
ohos:orientation="vertical"
>
<DependentLayout
ohos:id="$+id:head_layout"
ohos:height="match_content"
ohos:width="match_parent"
ohos:padding="10vp"
>
<Text
ohos:id="$+id:head_text"
ohos:height="match_content"
ohos:width="match_content"
ohos:center_in_parent="true"
ohos:text="下拉刷新"
ohos:text_size="17fp"
/>
<Image
ohos:id="$+id:head_image"
ohos:height="40vp"
ohos:width="40vp"
ohos:image_src="$media:up_image"
ohos:left_of="$+id:head_text"
ohos:vertical_center="true"
/>
</DependentLayout>
<ListContainer
ohos:id="$+id:list_container"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:background_element="white"
ohos:below="$id:head_layout"
/>
<DependentLayout
ohos:id="$+id:foot_layout"
ohos:height="70vp"
ohos:width="match_parent"
ohos:align_parent_bottom="true"
ohos:padding="10vp"
>
<Text
ohos:id="$+id:foot_text"
ohos:height="match_content"
ohos:width="match_content"
ohos:center_in_parent="true"
ohos:text="下拉刷新"
ohos:text_size="17fp"
/>
<Image
ohos:id="$+id:foot_image"
ohos:height="40vp"
ohos:width="40vp"
ohos:image_src="$media:up_image"
ohos:left_of="$+id:foot_text"
ohos:vertical_center="true"
/>
</DependentLayout>
</DependentLayout>
3、在自定义的类中加载布局,初始化各个组件
private void init() {
mRootLayout = (DependentLayout) LayoutScatter.getInstance(mContext)
.parse(ResourceTable.Layout_refresh_layout, null, true);
HiLog.error(LABEL, "init,rootLayout:%{public}s", mRootLayout);
mHeadLayout = (DependentLayout) mRootLayout.findComponentById(ResourceTable.Id_head_layout);
mFootLayout = (DependentLayout) mRootLayout.findComponentById(ResourceTable.Id_foot_layout);
mListContainer = (ListContainer) mRootLayout.findComponentById(ResourceTable.Id_list_container);
mHeadImage = (Image) mRootLayout.findComponentById(ResourceTable.Id_head_image);
mHeadText = (Text) mRootLayout.findComponentById(ResourceTable.Id_head_text);
mFootImage = (Image) mRootLayout.findComponentById(ResourceTable.Id_foot_image);
mFootText = (Text) mRootLayout.findComponentById(ResourceTable.Id_foot_text);
addComponent(mRootLayout);
}
4、设置监听事件
mRootLayout.setTouchEventListener(this::onTouchEvent);
@Override
public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
int action = touchEvent.getAction();
MmiPoint point = touchEvent.getPointerPosition(touchEvent.getIndex());
HiLog.error(LABEL, "action:%{public}s", action);
switch (action) {
case TouchEvent.PRIMARY_POINT_DOWN:
HiLog.error(LABEL, "onTouchEvent:%{public}s", "PRIMARY_POINT_DOWN");
mStartY = point.getY();
break;
case TouchEvent.PRIMARY_POINT_UP:
HiLog.error(LABEL, "onTouchEvent:%{public}s", "PRIMARY_POINT_UP");
HiLog.error(LABEL, "isPull:%{public}s", isPull);
if (isPull) {
int dis = (int) (mEndY - mStartY);
HiLog.error(LABEL, "dis:%{public}s", dis);
mHeadLayout.setMarginTop(0);
pullLoadingStatus();
isPull = false;
if (this.mRefreshListener != null) {
this.mRefreshListener.pullRefresh();
}
mListContainer.setEnabled(true);
// isLoading = true;
}
if (isUp) {
int dis = (int) (mStartY - mEndY);
HiLog.error(LABEL, "dis:%{public}s", dis);
mFootLayout.setMarginBottom(0);
HiLog.error(LABEL, "mFootLayoutHeight:%{public}s", mFootLayoutHeight);
mListContainer.setMarginBottom(mFootLayoutHeight);
this.mBaseItemProvider.notifyDataSetItemInserted(mBaseItemProvider.getCount()-1);
upLoadingStatus();
isUp = false;
if (this.mRefreshListener != null) {
this.mRefreshListener.upLoadingMore();
}
mListContainer.setEnabled(true);
}
break;
case TouchEvent.POINT_MOVE:
HiLog.error(LABEL, "onTouchEvent:%{public}s", "HOVER_POINTER_MOVE");
mEndY = point.getY();
HiLog.error(LABEL, "onTouchEvent,mEndY:%{public}s,mStartY:%{public}s", mEndY, mStartY);
HiLog.error(LABEL, "mListContainer.canScroll(DRAG_UP):%{public}s", mListContainer.canScroll(DRAG_UP));
HiLog.error(LABEL, "isSocllTop:%{public}s", isSocllTop);
if (!isLoading) {
if (isSocllTop && !isUp) {
if (mEndY - mStartY > 50) {
isPull = true;
if (pullAnimator != null) {
pullAnimator.stop();
mHeadImage.setRotation(0);
}
mHeadLayout.setVisibility(VISIBLE);
mHeadLayout.setMarginTop((int) (mEndY - mStartY) - 50);
if (mEndY - mStartY > 50 && mEndY - mStartY < 150) {
pullDefault();
} else {
pullStatus();
}
mListContainer.setEnabled(false);
}
}
if (!mListContainer.canScroll(DRAG_UP) && !isPull) {
if (mStartY - mEndY > 50) {
isUp = true;
if (upAnimator != null) {
upAnimator.stop();
mFootImage.setRotation(0);
}
HiLog.error(LABEL, "mStartY - mEndY:%{public}s", mStartY - mEndY);
mFootLayout.setVisibility(VISIBLE);
int des = (int) (mStartY - mEndY) - 50;
mListContainer.setMarginBottom(mFootLayoutHeight + des);
mFootLayout.setMarginBottom(des);
HiLog.error(LABEL, "mFootLayoutHeight:%{public}s", mFootLayoutHeight);
this.mBaseItemProvider.notifyDataSetItemInserted(mBaseItemProvider.getCount()-1);
if (mStartY - mEndY > 50 && mStartY - mEndY < 150) {
upDefault();
} else {
upStatus();
}
// mListContainer.setEnabled(true);
}
}
}
break;
default:
}
return true;
}
5、新建回调事件
package com.yan.refreshlistcontainer.listener;
public interface RefreshListener {
public void pullRefresh();
public void upLoadingMore();
}
6.提供方法供外部调用
//下拉刷新和上啦加载更多完成时调用
public void completeLoading() {
if (pullAnimator != null) {
pullAnimator.stop();
}
mHeadLayout.setVisibility(HIDE);
pullDefault();
if (upAnimator != null) {
upAnimator.stop();
}
mFootLayout.setVisibility(HIDE);
mListContainer.setMarginBottom(0);
upDefault();
}
//给ListContainer设置适配器
public void setItemProvider(BaseItemProvider baseItemProvider) {
this.mBaseItemProvider = baseItemProvider;
mListContainer.setItemProvider(this.mBaseItemProvider);
}
//设置上啦和下拉的监听事件
public void setRefreshListener(RefreshListener refreshListener) {
this.mRefreshListener = refreshListener;
}
7、ability使用
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:alignment="center"
ohos:orientation="vertical">
<com.yan.refreshlistcontainer.component.RefreshListContainer
ohos:id="$+id:refresh_list"
ohos:height="match_parent"
ohos:width="match_parent"/>
</DirectionalLayout>
package com.yan.refreshlistcontainer.slice;
import com.yan.refreshlistcontainer.ResourceTable;
import com.yan.refreshlistcontainer.bean.ListBean;
import com.yan.refreshlistcontainer.component.RefreshListContainer;
import com.yan.refreshlistcontainer.listener.RefreshListener;
import com.yan.refreshlistcontainer.provider.RefreshListProvider;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import java.util.ArrayList;
import java.util.List;
public class MainAbilitySlice extends AbilitySlice {
private RefreshListContainer mRefreshList;
private List<ListBean> mData = new ArrayList<>();
private MyEventHandler myHandler;
private RefreshListProvider refreshListProvider;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
mRefreshList = (RefreshListContainer) findComponentById(ResourceTable.Id_refresh_list);
initList();
EventRunner runner = EventRunner.create(true);
myHandler = new MyEventHandler(runner);
refreshListProvider = new RefreshListProvider(MainAbilitySlice.this, mData);
mRefreshList.setItemProvider(refreshListProvider);
mRefreshList.setRefreshListener(new RefreshListener() {
@Override
public void pullRefresh() {
ListBean mListBean = new ListBean();
mListBean.setAge(999);
mListBean.setName("刷新新增Item");
mData.add(0, mListBean);
myHandler.sendEvent(1000, 3000);
}
@Override
public void upLoadingMore() {
ListBean mListBean = new ListBean();
mListBean.setAge(999);
mListBean.setName("加载更多新增Item");
mData.add(mListBean);
myHandler.sendEvent(1000, 3000);
}
});
}
private class MyEventHandler extends EventHandler {
private MyEventHandler(EventRunner runner) {
super(runner);
}
// 重写实现processEvent方法
@Override
public void processEvent(InnerEvent event) {
super.processEvent(event);
if (event == null) {
return;
}
int eventId = event.eventId;
switch (eventId) {
case 1000:
getUITaskDispatcher().syncDispatch(new Runnable() {
@Override
public void run() {
refreshListProvider.notifyDataChanged();
mRefreshList.completeLoading();
}
});
break;
default:
break;
}
}
}
private void initList() {
for (int i = 0; i < 100; i++) {
ListBean mListBean = new ListBean();
mListBean.setAge(i);
mListBean.setName("测试" + i);
mData.add(mListBean);
}
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
}
至此大概的流程已经完成。