return isPullToRefreshEnabled;
}
/**
-
Returns whether the widget has disabled scrolling on the Refreshable View
-
while refreshing.
-
@return true if the widget has disabled scrolling while refreshing
*/
public final boolean isDisableScrollingWhileRefreshing() {
return disableScrollingWhileRefreshing;
}
/**
-
Returns whether the Widget is currently in the Refreshing state
-
@return true if the Widget is currently refreshing
*/
public final boolean isRefreshing() {
return state == REFRESHING || state == MANUAL_REFRESHING;
}
/**
-
By default the Widget disabled scrolling on the Refreshable View while
-
refreshing. This method can change this behaviour.
-
@param disableScrollingWhileRefreshing
-
- true if you want to disable scrolling while refreshing
*/
public final void setDisableScrollingWhileRefreshing(
boolean disableScrollingWhileRefreshing) {
this.disableScrollingWhileRefreshing = disableScrollingWhileRefreshing;
}
/**
-
Mark the current Refresh as complete. Will Reset the UI and hide the
-
Refreshing View
*/
public final void onRefreshComplete() {
if (state != PULL_TO_REFRESH) {
resetHeader();
if (onShowLayoutListener != null) {
onShowLayoutListener.onDismiss();
}
}
}
/**
-
Set OnRefreshListener for the Widget
-
@param listener
-
- Listener to be used when the Widget is set to Refresh
*/
public final void setOnRefreshListener(OnRefreshListener listener) {
onRefreshListener = listener;
}
/**
-
auto load headerLayout to refresh
-
@param listener
*/
public final void setFirstAutoPullUpToRefresh(OnRefreshListener listener) {
setRefreshingInternal(true, MODE_PULL_DOWN_TO_REFRESH);
listener.onRefresh(MODE_PULL_DOWN_TO_REFRESH);
}
/**
-
set refreshLable , default use null
-
@param pullLabel
-
@param releaseLabel
-
@param refreshingLabel
*/
public void setRefreshLabel(String pullLabel, String releaseLabel,
String refreshingLabel) {
if (pullLabel != null) {
setPullLabel(pullLabel);
}
if (releaseLabel != null) {
setReleaseLabel(releaseLabel);
}
if (refreshingLabel != null) {
setRefreshingLabel(refreshingLabel);
}
}
/**
-
A mutator to enable/disable Pull-to-Refresh for the current View
-
@param enable
-
Whether Pull-To-Refresh should be used
*/
public final void setPullToRefreshEnabled(boolean enable) {
this.isPullToRefreshEnabled = enable;
}
/**
-
Set Text to show when the Widget is being pulled, and will refresh when
-
released
-
@param releaseLabel
-
- String to display
*/
private void setReleaseLabel(String releaseLabel) {
if (null != headerLayout) {
headerLayout.setReleaseLabel(releaseLabel);
}
if (null != footerLayout) {
footerLayout.setReleaseLabel(releaseLabel);
}
}
/**
-
Set Text to show when the Widget is being Pulled
-
@param pullLabel
-
- String to display
*/
private void setPullLabel(String pullLabel) {
if (null != headerLayout) {
headerLayout.setPullLabel(pullLabel);
}
if (null != footerLayout) {
footerLayout.setPullLabel(pullLabel);
}
}
/**
-
Set Text to show when the Widget is refreshing
-
@param refreshingLabel
-
- String to display
*/
private void setRefreshingLabel(String refreshingLabel) {
if (null != headerLayout) {
headerLayout.setRefreshingLabel(refreshingLabel);
}
if (null != footerLayout) {
footerLayout.setRefreshingLabel(refreshingLabel);
}
}
public final void setRefreshing() {
this.setRefreshing(true);
}
/**
-
Sets the Widget to be in the refresh state. The UI will be updated to
-
show the ‘Refreshing’ view.
-
@param doScroll
-
- true if you want to force a scroll to the Refreshing view.
*/
public final void setRefreshing(boolean doScroll) {
if (!isRefreshing()) {
setRefreshingInternal(doScroll);
state = MANUAL_REFRESHING;
}
}
public final boolean hasPullFromTop() {
return currentMode != MODE_PULL_UP_TO_REFRESH;
}
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
@Override
public final boolean onTouchEvent(MotionEvent event) {
if (!isPullToRefreshEnabled) {
return false;
}
if (isRefreshing() && disableScrollingWhileRefreshing) {
return true;
}
if (event.getAction() == MotionEvent.ACTION_DOWN
&& event.getEdgeFlags() != 0) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE: {
if (isBeingDragged) {
if (Math.abs(event.getY() - downLocation) > 5
&& onShowLayoutListener != null) {
onShowLayoutListener.onShow();
}
lastMotionY = event.getY();
this.pullEvent();
return true;
}
break;
}
case MotionEvent.ACTION_DOWN: {
if (isReadyForPull()) {
downLocation = event.getY();
lastMotionY = initialMotionY = event.getY();
return true;
}
break;
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP: {
if (isBeingDragged) {
isBeingDragged = false;
if (state == RELEASE_TO_REFRESH && null != onRefreshListener) {
setRefreshingInternal(true);
onRefreshListener.onRefresh(currentMode);
} else {
smoothScrollTo(0);
if (onShowLayoutListener != null) {
onShowLayoutListener.onDismiss();
}
}
return true;
}
break;
}
}
return false;
}
// remeber to down location
private float downLocation = 0;
@Override
public final boolean onInterceptTouchEvent(MotionEvent event) {
if (!isPullToRefreshEnabled) {
return false;
}
if (isRefreshing() && disableScrollingWhileRefreshing) {
return true;
}
final int action = event.getAction();
if (action == MotionEvent.ACTION_CANCEL
|| action == MotionEvent.ACTION_UP) {
isBeingDragged = false;
return false;
}
if (action != MotionEvent.ACTION_DOWN && isBeingDragged) {
return true;
}
switch (action) {
case MotionEvent.ACTION_MOVE: {
if (isReadyForPull()) {
final float y = event.getY();
final float dy = y - lastMotionY;
final float yDiff = Math.abs(dy);
final float xDiff = Math.abs(event.getX() - lastMotionX);
if (yDiff > touchSlop && yDiff > xDiff) {
if ((mode == MODE_PULL_DOWN_TO_REFRESH || mode == MODE_BOTH)
&& dy >= 0.0001f && isReadyForPullDown()) {
lastMotionY = y;
isBeingDragged = true;
if (mode == MODE_BOTH) {
currentMode = MODE_PULL_DOWN_TO_REFRESH;
}
} else if ((mode == MODE_PULL_UP_TO_REFRESH || mode == MODE_BOTH)
&& dy <= 0.0001f && isReadyForPullUp()) {
lastMotionY = y;
isBeingDragged = true;
if (mode == MODE_BOTH) {
currentMode = MODE_PULL_UP_TO_REFRESH;
}
}
}
}
break;
}
case MotionEvent.ACTION_DOWN: {
if (isReadyForPull()) {
lastMotionY = initialMotionY = event.getY();
lastMotionX = event.getX();
isBeingDragged = false;
}
break;
}
case MotionEvent.ACTION_UP:
break;
}
setRefreshLabel(currentMode);
return isBeingDragged;
}
protected void addRefreshableView(Context context, T refreshableView) {
addView(refreshableView, new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, 0, 1.0f));
}
/**
-
This is implemented by derived classes to return the created View. If you
-
need to use a custom View (such as a custom ListView), override this
-
method and return an instance of your custom class.
-
Be sure to set the ID of the view in this method, especially if you’re
-
using a ListActivity or ListFragment.
-
@param context
-
@param attrs
-
AttributeSet from wrapped class. Means that anything you
-
include in the XML layout declaration will be routed to the
-
created View
-
@return New instance of the Refreshable View
*/
protected abstract T createRefreshableView(Context context,
AttributeSet attrs);
public final int getCurrentMode() {
return currentMode;
}
protected final LoadingLayout getFooterLayout() {
return footerLayout;
}
protected final LoadingLayout getHeaderLayout() {
return headerLayout;
}
protected final int getHeaderHeight() {
return headerHeight;
}
protected final int getMode() {
return mode;
}
/**
-
Implemented by derived class to return whether the View is in a state
-
where the user can Pull to Refresh by scrolling down.
-
@return true if the View is currently the correct state (for example, top
-
of a ListView)
*/
protected abstract boolean isReadyForPullDown();
/**
-
Implemented by derived class to return whether the View is in a state
-
where the user can Pull to Refresh by scrolling up.
-
@return true if the View is currently in the correct state (for example,
-
bottom of a ListView)
*/
protected abstract boolean isReadyForPullUp();
// ===========================================================
// Methods
// ===========================================================
protected void resetHeader() {
state = PULL_TO_REFRESH;
isBeingDragged = false;
if (null != headerLayout) {
headerLayout.reset();
}
if (null != footerLayout) {
footerLayout.reset();
}
smoothScrollTo(0);
}
/**
-
unless special requirements to call the method ,default call the method
-
{@link #setRefreshingInternal(boolean doScroll)}
-
@param doScroll
-
@param mode
*/
protected void setRefreshingInternal(boolean doScroll, int mode) {
state = REFRESHING;
setRefreshLabel(mode);
if (null != headerLayout) {
headerLayout.refreshing();
}
if (doScroll) {
-
smoothScrollTo(mode == MODE_PULL_DOWN_TO_REFRESH ? -headerHeight
- headerHeight);
}
}
/**
-
set last refresh time
-
@param time
*/
public void setRefreshTime(String time) {
TextView mHeaderTimeView = (TextView) headerLayout
.findViewById(R.id.xlistview_header_time);
mHeaderTimeView.setText(time);
}
public void setRefreshTime(long time){
TextView mHeaderTimeView = (TextView) headerLayout
.findViewById(R.id.xlistview_header_time);
mHeaderTimeView.setText(TimeUtil.getChatTime(time));
}
protected void setRefreshingInternal(boolean doScroll) {
state = REFRESHING;
setRefreshLabel(currentMode);
if (null != footerLayout) {
footerLayout.refreshing();
}
if (null != headerLayout) {
headerLayout.refreshing();
}
if (doScroll) {
-
smoothScrollTo(currentMode == MODE_PULL_DOWN_TO_REFRESH ? -headerHeight
- headerHeight);
}
}
private void setRefreshLabel(int mode) {
if (mode == MODE_PULL_DOWN_TO_REFRESH) {
setRefreshLabel(“涓嬫媺鍒锋柊”, “閲婃斁绔嬪嵆鍒锋柊”, “姝e湪鍒锋柊”);
}
if (mode == MODE_PULL_UP_TO_REFRESH) {
setRefreshLabel(“涓婃媺鑾峰彇鏇村”, “鏉惧紑鏄剧ず鏇村”, “姝e湪鍔犺浇”);
}
}
protected final void setHeaderScroll(int y) {
scrollTo(0, y);
}
protected final void smoothScrollTo(int y) {
if (null != currentSmoothScrollRunnable) {
currentSmoothScrollRunnable.stop();
}
if (this.getScrollY() != y) {
this.currentSmoothScrollRunnable = new SmoothScrollRunnable(
handler, getScrollY(), y);
handler.post(currentSmoothScrollRunnable);
}
}
public void init(int mode) {
// Loading View Strings
String pullLabel = context
.getString(R.string.pull_to_refresh_pull_label);
String refreshingLabel = context
.getString(R.string.pull_to_refresh_refreshing_label);
String releaseLabel = context
.getString(R.string.pull_to_refresh_release_label);
// Add Loading Views
if (mode == MODE_PULL_DOWN_TO_REFRESH || mode == MODE_BOTH) {
headerLayout = new LoadingLayout(context,MODE_PULL_DOWN_TO_REFRESH, releaseLabel, pullLabel,refreshingLabel);
addView(headerLayout, 0, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT));
measureView(headerLayout);
headerHeight = headerLayout.getMeasuredHeight();
}
if (mode == MODE_PULL_UP_TO_REFRESH || mode == MODE_BOTH) {
footerLayout = new LoadingLayout(context, MODE_PULL_UP_TO_REFRESH,releaseLabel, pullLabel, refreshingLabel);
addView(footerLayout, new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
measureView(footerLayout);
headerHeight = footerLayout.getMeasuredHeight();
}
// Styleables from XML
if (null != headerLayout) {
// headerLayout.setTextColor(Color.BLACK);
}
if (null != footerLayout) {
// footerLayout.setTextColor(Color.BLACK);
}
// Hide Loading Views
switch (mode) {
case MODE_BOTH:
setPadding(0, -headerHeight, 0, -headerHeight);
break;
case MODE_PULL_UP_TO_REFRESH:
setPadding(0, 0, 0, -headerHeight);
break;
case MODE_PULL_DOWN_TO_REFRESH:
default:
setPadding(0, -headerHeight, 0, 0);
break;
}
// If we’re not using MODE_BOTH, then just set currentMode to current
// mode
if (mode != MODE_BOTH) {
currentMode = mode;
}
this.mode = mode;
}
private void init(Context context, AttributeSet attrs) {
this.context = context;
setOrientation(LinearLayout.VERTICAL);
touchSlop = ViewConfiguration.getTouchSlop();
// Refreshable View
// By passing the attrs, we can add ListView/GridView params via XML
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
尾声
如果你想成为一个优秀的 Android 开发人员,请集中精力,对基础和重要的事情做深度研究。
对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。 整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。
这里,笔者分享一份从架构哲学的层面来剖析的视频及资料分享给大家梳理了多年的架构经验,筹备近6个月最新录制的,相信这份视频能给你带来不一样的启发、收获。
Android进阶学习资料库
一共十个专题,包括了Android进阶所有学习资料,Android进阶视频,Flutter,java基础,kotlin,NDK模块,计算机网络,数据结构与算法,微信小程序,面试题解析,framework源码!
大厂面试真题
PS:之前因为秋招收集的二十套一二线互联网公司Android面试真题 (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)
《2019-2021字节跳动Android面试历年真题解析》
-
自行下载直达领取链接:【GitHub】
-
以上进阶BATJ大厂学习资料可以免费分享给大家,需要完整版的朋友,【点这里可以看到全部内容】。
大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频**
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
[外链图片转存中…(img-aooq1RQu-1710662390068)]
尾声
如果你想成为一个优秀的 Android 开发人员,请集中精力,对基础和重要的事情做深度研究。
对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。 整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。
这里,笔者分享一份从架构哲学的层面来剖析的视频及资料分享给大家梳理了多年的架构经验,筹备近6个月最新录制的,相信这份视频能给你带来不一样的启发、收获。
[外链图片转存中…(img-IemUUMXH-1710662390069)]
Android进阶学习资料库
一共十个专题,包括了Android进阶所有学习资料,Android进阶视频,Flutter,java基础,kotlin,NDK模块,计算机网络,数据结构与算法,微信小程序,面试题解析,framework源码!
[外链图片转存中…(img-6jmxQoPy-1710662390069)]
大厂面试真题
PS:之前因为秋招收集的二十套一二线互联网公司Android面试真题 (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)
[外链图片转存中…(img-QuqRJsNb-1710662390069)]
《2019-2021字节跳动Android面试历年真题解析》
[外链图片转存中…(img-yLG0Q10H-1710662390070)]
-
自行下载直达领取链接:【GitHub】
-
以上进阶BATJ大厂学习资料可以免费分享给大家,需要完整版的朋友,【点这里可以看到全部内容】。