您的位置:首页 > 移动开发 > Android开发

android listview & toolbar形成的一种炫酷效果(外加一个圆形图片的实现)

2015-06-01 22:23 651 查看
界面的效果用到的技术都很基本, 但实现的思路很新颖, 代码和布局充满各种技巧, 值得学习和借鉴.

效果图:



原理图:



布局代码:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:roundIcon="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<!--模块一-->
<ImageView
android:id="@+id/top_bg"
android:scaleType="fitXY"
android:src="@drawable/example"
android:layout_width="match_parent"
android:layout_height="220dp" />

<View
android:id="@+id/filter_bg"
android:background="#00000000"
android:layout_width="match_parent"
android:layout_height="220dp" />

<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="#00000000"
android:minHeight="?attr/actionBarSize"
app:popupTheme="@style/Theme.AppCompat.Light.DarkActionBar"
app:theme="@style/Theme.AppCompat" />
<TextView
android:layout_marginTop="155dp"
android:textSize="30sp"
android:text="My Flexible Space"
android:textColor="#ffffff"
android:id="@+id/title"
android:padding="16dp"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

<com.temp.lin.temp1.RoundIcon
android:id="@+id/round_icon"
android:src="@drawable/round_icon"
roundIcon:borderWidth="0dp"
roundIcon:borderColor="#cfcfcf"
android:layout_marginBottom="-40dp"
android:layout_marginRight="22dp"
android:layout_alignParentRight="true"
android:layout_marginTop="180dp"
android:layout_width="80dp"
android:layout_height="80dp" />
<!--模块一-->

<!--模块二-->
<!--
wrap_content会全屏的了
作为listview的背景, 但不包括header view的背景
-->
<View
android:visibility="gone"
android:id="@+id/list_background"
android:background="#ffffff"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<!--
ListView 不能设置background, 不然在代码添加的headerView就也一样有background了
ListView背景默认是透明的
-->
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent"></ListView>
<!--模块二-->

</RelativeLayout>


实现代码:

RoundIcon.java

public class RoundIcon extends ImageView {
private Paint borderPaint;
private int cx=-1,cy=-1,radius;
private int borderColor,borderWidth;
public RoundIcon(Context context) {
super(context,null);
}
public RoundIcon(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a=getResources().obtainAttributes(attrs, R.styleable.roundIcon);
borderColor=a.getColor(R.styleable.roundIcon_borderColor,0xffffffff);
borderWidth= (int) a.getDimension(R.styleable.roundIcon_borderWidth, 0f);
a.recycle();
borderPaint=new Paint();
borderPaint.setAntiAlias(true);
borderPaint.setStyle(Paint.Style.STROKE);
borderPaint.setStrokeWidth(borderWidth);
borderPaint.setColor(borderColor);
borderPaint.setDither(true);
}

@Override
protected void onDraw(Canvas canvas) {
//        super.onDraw(canvas);
if (cx==-1){cx=getWidth()/2; radius=cx-borderWidth/2;}
if (cy==-1){cy=getHeight()/2;}
//draw border
canvas.drawCircle(cx,cy,radius,borderPaint);
//draw round picture
canvas.drawBitmap(getRoundBitmap(((BitmapDrawable) getDrawable()).getBitmap(), radius*2),
borderWidth / 2, borderWidth / 2, null);
}

private Bitmap getRoundBitmap(Bitmap bitmap, int len) {
Bitmap squareBitmap,scaleBitmap;
int bitmapW=bitmap.getWidth();
int bitmapH=bitmap.getHeight();
//
Matrix matrix = new Matrix();
float scale=Math.max(len/(bitmapW+0.0f),len/(bitmapH+0.0f));
matrix.postScale(scale,scale);
scaleBitmap=Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
//
bitmapW=scaleBitmap.getWidth();
bitmapH=scaleBitmap.getHeight();
if (bitmapH==bitmapW){
squareBitmap=scaleBitmap;
}else{
int size=bitmapH<bitmapW?bitmapH:bitmapW;
if (size!=len) size=len;
squareBitmap=Bitmap.createBitmap(scaleBitmap,0,0,size,size);
}
//
//        Log.e("len w h",len+" "+squareBitmap.getWidth()+" "+squareBitmap.getHeight());
Bitmap output=Bitmap.createBitmap(squareBitmap.getWidth(),squareBitmap.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas myCanvas=new Canvas(output);
Paint mPaint=new Paint();
mPaint.setAntiAlias(true);
mPaint.setFilterBitmap(true);
mPaint.setDither(true);
//PorterDuffXfermode一定要先画一个背景之后才能使用
//不然画不出东西
myCanvas.drawCircle(cx,cy,radius,mPaint);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
myCanvas.drawBitmap(squareBitmap,0,0,mPaint);
return output;
}
}

SildingUpWithImgActivity.java
public class SildingUpWithImgActivity extends Activity {

int topBgHeight,titleMarginTop;
private ImageView topBg;
private View filterBg,listBg;
private TextView title;
private RoundIcon roundIcon;
private ListView listView;
private Toolbar toolbar;
private int preScrollDist=0,curScrollDist=0;
private ScaleAnimation roundIconAnimSmall,roundIconAnimBig;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}

private void initView() {
final View headerView=new View(this);
headerView.setClickable(true);
//
topBg= (ImageView) findViewById(R.id.top_bg);
filterBg=findViewById(R.id.filter_bg);
topBg.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
topBg.getViewTreeObserver().removeGlobalOnLayoutListener(this);
topBgHeight = topBg.getLayoutParams().height;
//
AbsListView.LayoutParams layoutParams=
new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT,topBgHeight);
headerView.setLayoutParams(layoutParams);
ViewGroup.LayoutParams la=filterBg.getLayoutParams();
//
listBg.setTranslationY(topBgHeight);
}
});
//
title= (TextView) findViewById(R.id.title);
title.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
title.getViewTreeObserver().removeGlobalOnLayoutListener(this);
titleMarginTop=((RelativeLayout.LayoutParams)title.getLayoutParams()).topMargin;
}
});
//
roundIcon= (RoundIcon) findViewById(R.id.round_icon);
//
listBg=findViewById(R.id.list_background);
//
listView= (ListView) findViewById(R.id.listview);
listView.addHeaderView(headerView);
listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, getDatas()));
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) {
if (topBgHeight==0) return;
int dist = getScrollDist();
setTopBgParams(dist / 2);
setTitleParams(dist);
setRoundIconParams(dist);
setListViewParams(topBgHeight + dist);
}
});
//
toolbar= (Toolbar) findViewById(R.id.toolbar);
}

private int getScrollDist() {
if (listView.getChildCount()<1) return 0; //不然会空指针错误
int firstVisiblePosition=listView.getFirstVisiblePosition();
preScrollDist=curScrollDist;
curScrollDist=-listView.getChildAt(0).getTop();
//
if (firstVisiblePosition>=1){
curScrollDist+=topBgHeight;
firstVisiblePosition--;
}
View view=listView.getChildAt(1);
if (view!=null){
curScrollDist+=firstVisiblePosition*view.getHeight();
}
//
//        int dist=curScrollDist-preScrollDist;
//        Log.e("dist",curScrollDist+"");
return -curScrollDist;
}

private void setRoundIconParams(int dist) {
int max=0;
int min=-(topBgHeight-roundIcon.getHeight()/2);
float transY=getBetween(min,max,dist);
roundIcon.setTranslationY(transY);
//        Log.e("setRoundIconParams transY min",transY+" "+min);
if (transY/min>0.5&&roundIconAnimSmall==null){
if (roundIconAnimBig!=null){
roundIconAnimBig.cancel();
roundIconAnimBig=null;
}
roundIconAnimSmall=new ScaleAnimation(1f,0f,1f,0f);
roundIconAnimSmall.setFillAfter(true);
roundIconAnimSmall.setDuration(300);
roundIcon.startAnimation(roundIconAnimSmall);
}else if (transY/min<=0.5&&roundIconAnimBig==null){
if (roundIconAnimSmall!=null){
roundIconAnimSmall.cancel();
roundIconAnimSmall=null;
}
roundIconAnimBig=new ScaleAnimation(0f,1f,0f,1f);
roundIconAnimBig.setFillAfter(true);
roundIconAnimBig.setDuration(300);
roundIcon.startAnimation(roundIconAnimBig);
}
}

private void setTitleParams(int dist) {
int min=-(topBgHeight-title.getMeasuredHeight());
int max=0;
float transY=getBetween(min, max, dist);
title.setTranslationY(transY);
float ratio=1-transY/min/3;
//        Log.e("setTitleParams transY min",transY+" "+min);
title.setPivotX(0);
title.setPivotY(0);
title.setScaleX(ratio);
title.setScaleY(ratio);
}

private void setTopBgParams(int dist) {
int min=-topBgHeight/2;
int max=0;
float transY=getBetween(min, max, dist);
topBg.setTranslationY(transY);
filterBg.setTranslationY(transY);
//
float ratio=transY/min;
//mask: 0~255(滑到顶部)
int mask= (int) (ratio*0xff);
//        Log.e("mask",color+"");
if (mask<160){
int color=0x00000000|(mask<<24);
filterBg.setBackgroundColor(color);
toolbar.setBackgroundColor(0x00000000);
}else{
int color=0xff000000;
filterBg.setBackgroundColor(color);
toolbar.setBackgroundColor(color);
}
}

private void setListViewParams(int dist) {
int max=topBgHeight;
int min=0;
listBg.setTranslationY(getBetween(min,max,dist));
}

private int getBetween(int min,int max, int value){
return Math.min(Math.max(min,value),max);
}

private String[] getDatas() {
String[] datas=new String[40];
for (int i=0;i<datas.length;i++){
int j=i+1;
datas[i]="data id: "+j;
}
return datas;
}

}

谢谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: