gpt4 book ai didi

java - 如何使用 JazzyListView 实现 pullToRefreshListView?

转载 作者:行者123 更新时间:2023-11-30 03:12:43 25 4
gpt4 key购买 nike

我给你一些提示链接:

  1. https://github.com/twotoasters/jazzylistview

  2. https://play.google.com/store/apps/details?id=com.twotoasters.jazzylistview.sample

我已经实现了 JazzylistView,但我还想用 PullToRefresh ListView 实现 JazzylistView。这可能吗?任何人都知道这个答案,请帮助我?

最佳答案

我找到了这个解决方案。只需将下面的代码复制粘贴到库中的 PullToRefreshListView .java 文件中。

package com.smartupdater.widget;

import java.text.SimpleDateFormat;
import java.util.Date;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.LinearInterpolator;
import android.view.animation.OvershootInterpolator;
import android.view.animation.RotateAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.notecrate.R;
import com.smartupdater.utils.Constants;


public class PullToRefreshListView extends ListView {

private final JazzyHelper mHelper;
private static final float PULL_RESISTANCE = 1.7f;
private static final int BOUNCE_ANIMATION_DURATION = 700;
private static final int BOUNCE_ANIMATION_DELAY = 100;
private static final float BOUNCE_OVERSHOOT_TENSION = 1.4f;
private static final int ROTATE_ARROW_ANIMATION_DURATION = 250;

private static enum State {
PULL_TO_REFRESH, RELEASE_TO_REFRESH, REFRESHING
}

/**
* Interface to implement when you want to get notified of 'pull to refresh'
* events. Call setOnRefreshListener(..) to activate an OnRefreshListener.
*/
public interface OnRefreshListener {

/**
* Method to be called when a refresh is requested
*/
public void onRefresh();
}

private static int measuredHeaderHeight;

private boolean scrollbarEnabled;
private boolean bounceBackHeader;
private boolean lockScrollWhileRefreshing;
private boolean showLastUpdatedText;
private String pullToRefreshText;
private String releaseToRefreshText;
private String refreshingText;
private String lastUpdatedText;
private SimpleDateFormat lastUpdatedDateFormat = new SimpleDateFormat("dd/MM HH:mm");

private float previousY;
private int headerPadding;
private boolean hasResetHeader;
private long lastUpdated = -1;
private State state;
private LinearLayout headerContainer;
private RelativeLayout header;
private RotateAnimation flipAnimation;
private RotateAnimation reverseFlipAnimation;
private ImageView image;
private ProgressBar spinner;
private TextView text;
private TextView lastUpdatedTextView;
private OnItemClickListener onItemClickListener;
private OnItemLongClickListener onItemLongClickListener;
private OnRefreshListener onRefreshListener;

public PullToRefreshListView(Context context) {
super(context);
mHelper = init(context, null);
init();
}

public PullToRefreshListView(Context context, AttributeSet attrs) {
super(context, attrs);
mHelper = init(context, attrs);
init();
}

public PullToRefreshListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mHelper = init(context, attrs);
init();
}

private JazzyHelper init(Context context, AttributeSet attrs) {
JazzyHelper helper = new JazzyHelper(context, attrs);
super.setOnScrollListener(helper);
return helper;
}

@Override
public final void setOnScrollListener(OnScrollListener l) {
mHelper.setOnScrollListener(l);
}

public void setTransitionEffect(int transitionEffect) {
mHelper.setTransitionEffect(transitionEffect);
}

public void setShouldOnlyAnimateNewItems(boolean onlyAnimateNew) {
mHelper.setShouldOnlyAnimateNewItems(onlyAnimateNew);
}

public void setShouldOnlyAnimateFling(boolean onlyFling) {
mHelper.setShouldOnlyAnimateFling(onlyFling);
}

public void setSimulateGridWithList(boolean simulateGridWithList) {
mHelper.setSimulateGridWithList(simulateGridWithList);
setClipChildren(!simulateGridWithList);
}

public void setMaxAnimationVelocity(int itemsPerSecond) {
mHelper.setMaxAnimationVelocity(itemsPerSecond);
}

@Override
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}

@Override
public void setOnItemLongClickListener(OnItemLongClickListener onItemLongClickListener) {
this.onItemLongClickListener = onItemLongClickListener;
}

/**
* Activate an OnRefreshListener to get notified on 'pull to refresh'
* events.
*
* @param onRefreshListener
* The OnRefreshListener to get notified
*/
public void setOnRefreshListener(OnRefreshListener onRefreshListener) {
this.onRefreshListener = onRefreshListener;
}

/**
* @return If the list is in 'Refreshing' state
*/
public boolean isRefreshing() {
return state == State.REFRESHING;
}

/**
* Default is false. When lockScrollWhileRefreshing is set to true, the list
* cannot scroll when in 'refreshing' mode. It's 'locked' on refreshing.
*
* @param lockScrollWhileRefreshing
*/
public void setLockScrollWhileRefreshing(boolean lockScrollWhileRefreshing) {
this.lockScrollWhileRefreshing = lockScrollWhileRefreshing;
}

/**
* Default is false. Show the last-updated date/time in the 'Pull ro
* Refresh' header. See 'setLastUpdatedDateFormat' to set the date/time
* formatting.
*
* @param showLastUpdatedText
*/
public void setShowLastUpdatedText(boolean showLastUpdatedText) {
this.showLastUpdatedText = showLastUpdatedText;
if (!showLastUpdatedText)
lastUpdatedTextView.setVisibility(View.GONE);
}

/**
* Default: "dd/MM HH:mm". Set the format in which the last-updated
* date/time is shown. Meaningless if 'showLastUpdatedText == false
* (default)'. See 'setShowLastUpdatedText'.
*
* @param lastUpdatedDateFormat
*/
public void setLastUpdatedDateFormat(SimpleDateFormat lastUpdatedDateFormat) {
this.lastUpdatedDateFormat = lastUpdatedDateFormat;
}

/**
* Explicitly set the state to refreshing. This is useful when you want to
* show the spinner and 'Refreshing' text when the refresh was not triggered
* by 'pull to refresh', for example on start.
*/
public void setRefreshing() {
state = State.REFRESHING;
scrollTo(0, 0);
setUiRefreshing();
setHeaderPadding(0);
}

/**
* Set the state back to 'pull to refresh'. Call this method when refreshing
* the data is finished.
*/
public void onRefreshComplete() {
state = State.PULL_TO_REFRESH;
resetHeader();
lastUpdated = System.currentTimeMillis();
}

/**
* Change the label text on state 'Pull to Refresh'
*
* @param pullToRefreshText
* Text
*/
public void setTextPullToRefresh(String pullToRefreshText) {
this.pullToRefreshText = pullToRefreshText;
if (state == State.PULL_TO_REFRESH) {
text.setText(pullToRefreshText);
}
}

/**
* Change the label text on state 'Release to Refresh'
*
* @param releaseToRefreshText
* Text
*/
public void setTextReleaseToRefresh(String releaseToRefreshText) {
this.releaseToRefreshText = releaseToRefreshText;
if (state == State.RELEASE_TO_REFRESH) {
text.setText(releaseToRefreshText);
}
}

/**
* Change the label text on state 'Refreshing'
*
* @param refreshingText
* Text
*/
public void setTextRefreshing(String refreshingText) {
this.refreshingText = refreshingText;
if (state == State.REFRESHING) {
text.setText(refreshingText);
}
}

private void init() {
setVerticalFadingEdgeEnabled(false);

headerContainer = (LinearLayout) LayoutInflater.from(getContext()).inflate(R.layout.layout_pulldown_header, null);
header = (RelativeLayout) headerContainer.findViewById(R.id.ptr_id_header);
text = (TextView) header.findViewById(R.id.ptr_id_text);
lastUpdatedTextView = (TextView) header.findViewById(R.id.ptr_id_last_updated);
image = (ImageView) header.findViewById(R.id.ptr_id_image);
spinner = (ProgressBar) header.findViewById(R.id.ptr_id_spinner);

pullToRefreshText = getContext().getString(R.string.ptr_pull_to_refresh);
releaseToRefreshText = getContext().getString(R.string.ptr_release_to_refresh);
refreshingText = getContext().getString(R.string.ptr_refreshing);
lastUpdatedText = getContext().getString(R.string.ptr_last_updated);

flipAnimation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
flipAnimation.setInterpolator(new LinearInterpolator());
flipAnimation.setDuration(ROTATE_ARROW_ANIMATION_DURATION);
flipAnimation.setFillAfter(true);

reverseFlipAnimation = new RotateAnimation(-180, 0, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
reverseFlipAnimation.setInterpolator(new LinearInterpolator());
reverseFlipAnimation.setDuration(ROTATE_ARROW_ANIMATION_DURATION);
reverseFlipAnimation.setFillAfter(true);

addHeaderView(headerContainer);
setState(State.PULL_TO_REFRESH);
scrollbarEnabled = isVerticalScrollBarEnabled();

ViewTreeObserver vto = header.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new PTROnGlobalLayoutListener());

super.setOnItemClickListener(new PTROnItemClickListener());
super.setOnItemLongClickListener(new PTROnItemLongClickListener());
}

private void setHeaderPadding(int padding) {
headerPadding = padding;
// Log.d(Constants.TAG, "Header Container=" + headerContainer +
// " Header=" + header + " Header Padding=" + headerPadding);
if (header != null) {
MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) header.getLayoutParams();
mlp.setMargins(0, Math.round(padding), 0, 0);
header.setLayoutParams(mlp);
}
}

@Override
public boolean onTouchEvent(MotionEvent event) {
if (lockScrollWhileRefreshing && (state == State.REFRESHING || getAnimation() != null && !getAnimation().hasEnded())) {
return true;
}

switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (getFirstVisiblePosition() == 0)
previousY = event.getY();
else
previousY = -1;
break;

case MotionEvent.ACTION_UP:
if (previousY != -1 && (state == State.RELEASE_TO_REFRESH || getFirstVisiblePosition() == 0)) {
switch (state) {
case RELEASE_TO_REFRESH:
setState(State.REFRESHING);
bounceBackHeader();

break;

case PULL_TO_REFRESH:
resetHeader();
break;
}
}
break;

case MotionEvent.ACTION_MOVE:
if (previousY != -1) {
float y = event.getY();
float diff = y - previousY;
if (diff > 0)
diff /= PULL_RESISTANCE;
previousY = y;

int newHeaderPadding = Math.max(Math.round(headerPadding + diff), -header.getHeight());

if (newHeaderPadding != headerPadding && state != State.REFRESHING) {
setHeaderPadding(newHeaderPadding);

if (state == State.PULL_TO_REFRESH && headerPadding > 0) {
setState(State.RELEASE_TO_REFRESH);

image.clearAnimation();
image.startAnimation(flipAnimation);
} else if (state == State.RELEASE_TO_REFRESH && headerPadding < 0) {
setState(State.PULL_TO_REFRESH);

image.clearAnimation();
image.startAnimation(reverseFlipAnimation);
}

return true;
}
}

break;
}

return super.onTouchEvent(event);
}

private void bounceBackHeader() {
int yTranslate = state == State.REFRESHING ? header.getHeight() - headerContainer.getHeight() : -headerContainer.getHeight()
- headerContainer.getTop();

TranslateAnimation bounceAnimation = new TranslateAnimation(TranslateAnimation.ABSOLUTE, 0, TranslateAnimation.ABSOLUTE, 0,
TranslateAnimation.ABSOLUTE, 0, TranslateAnimation.ABSOLUTE, yTranslate);

bounceAnimation.setDuration(BOUNCE_ANIMATION_DURATION);
bounceAnimation.setFillEnabled(true);
bounceAnimation.setFillAfter(false);
bounceAnimation.setFillBefore(true);
bounceAnimation.setInterpolator(new OvershootInterpolator(BOUNCE_OVERSHOOT_TENSION));
bounceAnimation.setAnimationListener(new HeaderAnimationListener(yTranslate));

startAnimation(bounceAnimation);
}

private void resetHeader() {
if (getFirstVisiblePosition() > 0) {
setHeaderPadding(-header.getHeight());
setState(State.PULL_TO_REFRESH);
return;
}

if (getAnimation() != null && !getAnimation().hasEnded()) {
bounceBackHeader = true;
} else {
bounceBackHeader();
}
}

private void setUiRefreshing() {
spinner.setVisibility(View.VISIBLE);
image.clearAnimation();
image.setVisibility(View.INVISIBLE);
text.setText(refreshingText);
}

private void setState(State state) {
this.state = state;
switch (state) {
case PULL_TO_REFRESH:
spinner.setVisibility(View.INVISIBLE);
image.setVisibility(View.VISIBLE);
text.setText(pullToRefreshText);

if (showLastUpdatedText && lastUpdated != -1) {
lastUpdatedTextView.setVisibility(View.VISIBLE);
lastUpdatedTextView.setText(String.format(lastUpdatedText, lastUpdatedDateFormat.format(new Date(lastUpdated))));
}

break;

case RELEASE_TO_REFRESH:
spinner.setVisibility(View.INVISIBLE);
image.setVisibility(View.VISIBLE);
text.setText(releaseToRefreshText);
break;

case REFRESHING:
setUiRefreshing();

lastUpdated = System.currentTimeMillis();
if (onRefreshListener == null) {
setState(State.PULL_TO_REFRESH);
} else {
onRefreshListener.onRefresh();
}

break;
}
}

@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);

if (!hasResetHeader) {
if (measuredHeaderHeight > 0 && state != State.REFRESHING) {
setHeaderPadding(-measuredHeaderHeight);
}

hasResetHeader = true;
}
}

private class HeaderAnimationListener implements AnimationListener {

private int height, translation;
private State stateAtAnimationStart;

public HeaderAnimationListener(int translation) {
this.translation = translation;
}

@Override
public void onAnimationStart(Animation animation) {
stateAtAnimationStart = state;

android.view.ViewGroup.LayoutParams lp = getLayoutParams();
height = lp.height;
lp.height = getHeight() - translation;
setLayoutParams(lp);

if (scrollbarEnabled) {
setVerticalScrollBarEnabled(false);
}
}

@Override
public void onAnimationEnd(Animation animation) {
setHeaderPadding(stateAtAnimationStart == State.REFRESHING ? 0 : -measuredHeaderHeight - headerContainer.getTop());
setSelection(0);

android.view.ViewGroup.LayoutParams lp = getLayoutParams();
lp.height = height;
setLayoutParams(lp);

if (scrollbarEnabled) {
setVerticalScrollBarEnabled(true);
}

if (bounceBackHeader) {
bounceBackHeader = false;

postDelayed(new Runnable() {

@Override
public void run() {
resetHeader();
}
}, BOUNCE_ANIMATION_DELAY);
} else if (stateAtAnimationStart != State.REFRESHING) {
setState(State.PULL_TO_REFRESH);
}
}

@Override
public void onAnimationRepeat(Animation animation) {
}
}

private class PTROnGlobalLayoutListener implements OnGlobalLayoutListener {

@Override
public void onGlobalLayout() {
int initialHeaderHeight = header.getHeight();

if (initialHeaderHeight > 0) {
measuredHeaderHeight = initialHeaderHeight;

if (measuredHeaderHeight > 0 && state != State.REFRESHING) {
setHeaderPadding(-measuredHeaderHeight);
requestLayout();
}
}

getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
}

private class PTROnItemClickListener implements OnItemClickListener {

@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
hasResetHeader = false;

if (onItemClickListener != null && state == State.PULL_TO_REFRESH) {
// Passing up onItemClick. Correct position with the number of
// header views
onItemClickListener.onItemClick(adapterView, view, position - getHeaderViewsCount(), id);
}
}
}

private class PTROnItemLongClickListener implements OnItemLongClickListener {

@Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int position, long id) {
hasResetHeader = false;

if (onItemLongClickListener != null && state == State.PULL_TO_REFRESH) {
// Passing up onItemLongClick. Correct position with the number
// of header views
return onItemLongClickListener.onItemLongClick(adapterView, view, position - getHeaderViewsCount(), id);
}

return false;
}
}
}

关于java - 如何使用 JazzyListView 实现 pullToRefreshListView?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20678115/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com