android 滑动顶部布局停留

 

看过很多不错的布局停留效果,代码思路差不多,整合了一下项目里的技术点,提出了这个功能。为的是纪录起来,怕哪天自己忘记了

这个功能以前看起来跟高大上,以为又是onLayout,invalidate  等等去解决,果断做了伸手党

最近捡起来看了下,其实发现只需要用动画就可以了。

这个顶部停留的layout 其实可以写在你的list层,不过被隐藏了,当items 滑动到顶部消失不见时,让它visible就可以了。

思路就在listview的onScroll里面,在里面控制就可以了。

思路分为以下:

先出去当前View与下一个View的位置:其中overflowView 为停留布局

 

View nextView = view.getChildAt(1);
View currentView = view.getChildAt(0);
int position[] = new int[2];
if (null != nextView) {
	nextView.getLocationInWindow(position);
	int nextViewPositionY = position[1];
	if (overFlowViewPosition == 0) {
		获取在当前窗口内的绝对坐标
		overflowView.getLocationInWindow(position);
		//location [0]--->x坐标,location [1]--->y坐标
		overFlowViewPosition = position[1];
	}
}
int gap = nextViewPositionY - overFlowViewPosition - overflowView.getHeight();//计算距离
if (gap < 0) {
	// Following ListView
	objectAnimatorY.setFloatValues(gap);
} else {
	objectAnimatorY.setFloatValues(0);
}

纪录当前的view的位置:

 

if (lastVisiblePosition != firstVisibleItem) {
	testBaseAdapter.initializeHeaderViews(testBaseAdapter.getItem(firstVisibleItem).toString(), viewHolder);
	此方法刷新顶部内容
}
lastVisiblePosition = firstVisibleItem;
Log.d("firstVisibleItem =", "firstVisibleItem = " + firstVisibleItem);

当前布局的滑动:

 

 

if (null != currentView) {
	Log.d("", "currentView top = " + currentView.getTop());
	//当前item距离顶部的距离
	if (currentView.getTop() >= 0) {
		objectAnimatorAlpha.setFloatValues(0);
	} else {
		objectAnimatorAlpha.setFloatValues(1);
		overflowView.setVisibility(View.VISIBLE);
	}
}


思路就是这样 完整代码如下:

 

 

package com.wheat.test.activity;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.TextView;

import com.nineoldandroids.animation.ObjectAnimator;
import com.wheat.test.R;
import com.wheat.test.adapter.TestBaseAdapter;

/**
 * Created by wheat on 15/9/21.
 */
public class TestActivity extends Activity {

    private String[] item = new String[]{};
    private TestBaseAdapter testBaseAdapter;
    private ListView listView = null;
    private ObjectAnimator objectAnimatorY, objectAnimatorAlpha;
    private int overFlowViewPosition;
    private View overflowView = null;

    private int lastVisiblePosition = -1;

    private TestBaseAdapter.ViewHolder viewHolder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test_main_layout);
        viewHolder = new TestBaseAdapter.ViewHolder();
        initHeaderView();
        listView = (ListView) findViewById(R.id.my_list);
        item = getResources().getStringArray(R.array.test_data);
        testBaseAdapter = new TestBaseAdapter(item, this);
        listView.setAdapter(testBaseAdapter);
        listView.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {

            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                View nextView = view.getChildAt(1);
                View currentView = view.getChildAt(0);
                int position[] = new int[2];
                if (null != nextView) {
                    nextView.getLocationInWindow(position);
                    int nextViewPositionY = position[1];
                    if (overFlowViewPosition == 0) {
                        获取在当前窗口内的绝对坐标
                        overflowView.getLocationInWindow(position);
                        //location [0]--->x坐标,location [1]--->y坐标
                        overFlowViewPosition = position[1];
                    }
                    int gap = nextViewPositionY - overFlowViewPosition - overflowView.getHeight();
                    Log.d("onScroll :", "gap = " + gap + " nextViewPositionY = " + nextViewPositionY + " overFlowViewPosition" + overFlowViewPosition + " getHeight() =" + overflowView.getHeight());

                    if (gap < 0) {
                        // Following ListView
                        objectAnimatorY.setFloatValues(gap);
                    } else {
                        objectAnimatorY.setFloatValues(0);
                    }


                    if (lastVisiblePosition != firstVisibleItem) {
                        testBaseAdapter.initializeHeaderViews(testBaseAdapter.getItem(firstVisibleItem).toString(), viewHolder);
                    }
                    lastVisiblePosition = firstVisibleItem;

                    Log.d("firstVisibleItem =", "firstVisibleItem = " + firstVisibleItem);

                } else if (currentView != null) {
                    testBaseAdapter.initializeHeaderViews(testBaseAdapter.getItem(firstVisibleItem).toString(),
                            viewHolder);
                    lastVisiblePosition = -1;
                    objectAnimatorY.setFloatValues(0);
                }

                if (null != currentView) {

                    Log.d("", "currentView top = " + currentView.getTop());
                    //当前item距离顶部的距离
                    if (currentView.getTop() >= 0) {
                        objectAnimatorAlpha.setFloatValues(0);
                    } else {
//                        if (!mPullRefreshLayout.isRefreshing()) {
                        objectAnimatorAlpha.setFloatValues(1);
                        overflowView.setVisibility(View.VISIBLE);
//                        }
                    }
//                    Log.d("", "currentView visibility = " + currentView.getVisibility());
                }


                objectAnimatorAlpha.start();
                objectAnimatorY.start();
            }
        });
    }

    private void initHeaderView() {
        overflowView = findViewById(R.id.photo_show_overflow_header);
        overflowView.setBackgroundColor(Color.argb(242, 253, 251, 251));// alpha
        objectAnimatorY = ObjectAnimator.ofFloat(overflowView, "y", 0).setDuration(0);
        objectAnimatorAlpha = ObjectAnimator.ofFloat(overflowView, "alpha", 0).setDuration(0);
        TextView mTvNickname = (TextView) findViewById(R.id.tv_nickname);
        viewHolder.setTvNickname(mTvNickname);
    }
}


适配器方法:

 

 

package com.wheat.test.adapter;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.wheat.test.R;

import java.net.ContentHandler;

/**
 * Created by wheat on 15/9/21.
 */
public class TestBaseAdapter extends BaseAdapter {

    String[] item;

    private Context mContext;

    public TestBaseAdapter(String[] item, Context context) {
        this.item = item;
        this.mContext = context;
    }

    @Override
    public int getCount() {
        return item.length;
    }

    @Override
    public Object getItem(int position) {
        return item[position];
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            ViewHolder viewHolder = new ViewHolder();
            convertView = View.inflate(mContext, R.layout.base_header_detail_view, null);
            viewHolder.tvNickname = (TextView) convertView.findViewById(R.id.tv_nickname);
            convertView.setTag(viewHolder);
        }
        ViewHolder holder = (ViewHolder) convertView.getTag();
        holder.tvNickname.setText(item[position]);
        return convertView;
    }

    public void initializeHeaderViews(final String item, ViewHolder holder) {
        if (item == null || holder == null)
            return;
        holder.tvNickname.setText(item);
    }

    public static class ViewHolder {
        private TextView tvNickname;

        public void setTvNickname(TextView tvNickname) {
            this.tvNickname = tvNickname;
        }

        public TextView getTvNickname() {
            return tvNickname;
        }
    }
}

 

 

 



 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值