看过很多不错的布局停留效果,代码思路差不多,整合了一下项目里的技术点,提出了这个功能。为的是纪录起来,怕哪天自己忘记了
这个功能以前看起来跟高大上,以为又是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;
}
}
}