私のプロジェクトでGoogle Plusアプリケーションを模倣しようとしています。これは現在リファレンスのようです。
スクロール時のリストビュー効果は本当にいいですし、同様のことをしたいと思います。
私はLayoutAnimationControllerから始めました http://Android-er.blogspot.be/2009/10/listview-and-listactivity-layout.html
LayoutAnimationController controller
= AnimationUtils.loadLayoutAnimation(
this, R.anim.list_layout_controller);
getListView().setLayoutAnimation(controller);
すべての要素がアニメーション化されているわけではないので、それは悪いようです:
だから私はアダプターのgetViewを使用してこれを使用することで終わりました:
AnimationSet set = new AnimationSet(true);
Animation animation = new AlphaAnimation(0.0f, 1.0f);
animation.setDuration(800);
set.addAnimation(animation);
animation = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0.0f,Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 1.0f,Animation.RELATIVE_TO_SELF, 0.0f
);
animation.setDuration(600);
set.addAnimation(animation);
row.startAnimation(set);
結果は素晴らしいです、そして私はそれで本当に満足しています!
残念ながら、それは私がリストの上から下にスクロールしたときにのみ機能します!
反対側にスクロールするときにそれを動作させたいので、TranslateAnimationを少し変更する必要があります。
だから私の質問、私のアダプターを上または下にスクロールしたかどうかを検出する方法はありますか?
これは私が出会った最も簡単でシンプルな方法です。そしてそれは魅力のように働きます。
view.addOnScrollListener(new View.OnScrollListener() {
@Override
public void onScrolled(@NonNull View view, int dx, int dy) {
if (dy > 0) {
//Scrolling down
} else if (dy < 0) {
//Scrolling up
}
}
});
OnScrollListener
をListView
に割り当てます。ユーザーが上または下にスクロールしているかどうかを示すフラグを作成します。現在のfirst表示アイテムの位置が以前のfirst表示アイテムの位置。そのチェックをonScrollStateChanged()
の中に入れます。
サンプルコード:
_private int mLastFirstVisibleItem;
private boolean mIsScrollingUp;
public void onScrollStateChanged(AbsListView view, int scrollState) {
final ListView lw = getListView();
if (view.getId() == lw.getId()) {
final int currentFirstVisibleItem = lw.getFirstVisiblePosition();
if (currentFirstVisibleItem > mLastFirstVisibleItem) {
mIsScrollingUp = false;
} else if (currentFirstVisibleItem < mLastFirstVisibleItem) {
mIsScrollingUp = true;
}
mLastFirstVisibleItem = currentFirstVisibleItem;
}
}
_
getView()
でmIsScrollingUp
がtrueまたはfalseかどうかを確認し、それに応じてアニメーションを割り当てます。
私はこれを行うことで終わりました:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.i("",position+" - "+lastposition);
if (position >= lastposition)
animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF,
0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 1.0f,
Animation.RELATIVE_TO_SELF, 0.0f);
else
animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF,
0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, -1.0f,
Animation.RELATIVE_TO_SELF, 0.0f);
animation.setDuration(600);
set.addAnimation(animation);
row.startAnimation(set);
lastposition = position;
}
より複雑なソリューション(リストビューで長いアイテムの高さで作業)
カスタムリストビューを作成する
public class ScrollDetectingListView extends ListView {
public ScrollDetectingListView(Context context) {
super(context);
}
public ScrollDetectingListView(Context context, AttributeSet attrs) {
super(context,attrs);
}
public ScrollDetectingListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
//we need this protected method for scroll detection
public int getVerticalScrollOffset() {
return computeVerticalScrollOffset();
}
}
OnScrollをオーバーライド
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
private int mInitialScroll = 0;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
int scrolledOffset = listView.getVerticalScrollOffset();
if (scrolledOffset!=mInitialScroll) {
//if scroll position changed
boolean scrollUp = (scrolledOffset - mInitialScroll) < 0;
mInitialScroll = scrolledOffset;
}
}
});
受け入れられた回答は、実際に上下にスクロールすることを「検出」するものではありません。現在表示されているアイテムが非常に大きい場合は機能しません。 onTouchListener
を使用する方法です。
これは私が使用したコードスニペットです:
listView.setOnTouchListener(new View.OnTouchListener() {
float initialY, finalY;
boolean isScrollingUp;
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = MotionEventCompat.getActionMasked(event);
switch(action) {
case (MotionEvent.ACTION_DOWN):
initialY = event.getY();
case (MotionEvent.ACTION_UP):
finalY = event.getY();
if (initialY < finalY) {
Log.d(TAG, "Scrolling up");
isScrollingUp = true;
} else if (initialY > finalY) {
Log.d(TAG, "Scrolling down");
isScrollingUp = false;
}
default:
}
if (isScrollingUp) {
// do animation for scrolling up
} else {
// do animation for scrolling down
}
return false; // has to be false, or it will freeze the listView
}
});
これを試して 。お役に立てば幸いです。 @Gal Rom Answerからのロジック。
lv.setOnScrollListener(new OnScrollListener() {
private int mLastFirstVisibleItem;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if(mLastFirstVisibleItem<firstVisibleItem)
{
Log.i("SCROLLING DOWN","TRUE");
}
if(mLastFirstVisibleItem>firstVisibleItem)
{
Log.i("SCROLLING UP","TRUE");
}
mLastFirstVisibleItem=firstVisibleItem;
}
});
これが私のアプローチです:スクロールした量に関するフィードバックがすぐに得られます:OnScroll
、リストの最初の項目のトップポジションを取得できます。実際のスクロール位置情報をすぐに取得するのはかなり信頼できます。
listView.getChildAt(0).getTop()
list.setOnScrollListener(new OnScrollListener() {
int last_item;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if(last_item<firstVisibleItem+visibleItemCount-1){
System.out.println("List is scrolling upwards");
}
else if(last_item>firstVisibleItem+visibleItemCount-1){
System.out.println("List is scrolling downwards");
}
last_item = firstVisibleItem+visibleItemCount-1;
}
});
最後に表示されたアイテムの位置に基づいて、リストビューが上向きか下向きかを決定します。
ビューなどの位置に依存しない一般的なソリューション。垂直スクロールオフセットを確認して、前のスクロールオフセットと比較してください。新しい値が古い値より大きい場合、ユーザーは下にスクロールしており、その逆も同様です。
// [START check vertical scroll direction]
int oldScrollOffset = 0;
listView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
@Override
public void onScrollChange(View view, int i, int i1, int i2, int i3) {
Boolean scrollDirectionDown;
int newScrollOffset = listView.computeVerticalScrollOffset();
if (newScrollOffset > oldScrollOffset) {
scrollDirectionDown = true;
} else {
scrollDirectionDown = false;
}
oldScrollOffset = newScrollOffset;
if (scrollDirectionDown) {
// Update accordingly for scrolling down
Log.d(TAG, "scrolling down");
} else {
// Update accordingly for scrolling up
Log.d(TAG, "scrolling up");
}
});
// [END check vertical scroll direction]
私はこれよりはるかに簡単なソリューションを使用しました:
public class ScrollDetectingListView extends ListView
...
setOnScrollListener( new OnScrollListener()
{
private int mInitialScroll = 0;
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount)
{
int scrolledOffset = computeVerticalScrollOffset();
boolean scrollUp = scrolledOffset > mInitialScroll;
mInitialScroll = scrolledOffset;
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
}