Android 仿美團網,大眾點評購買框懸浮效果,仿美團詳情頁,可下拉放大圖片,向上滾動圖片,鬆手有動畫
阿新 • • 發佈:2019-01-02
先看效果圖
直接上程式碼註釋都寫到程式碼裡面了:
自定義的ScrollView
package mm.shandong.com.testmtxqcomplex.myui; import android.content.Context; import android.util.AttributeSet; import android.widget.ScrollView; /** * Created by 安卓學習手冊 on 2016/7/29. */ public class MyScrollView extends ScrollView { private OnScrollChangedListener onScrollChangedListener; public void setOnScrollChangedListener(OnScrollChangedListener onScrollChangedListener) { this.onScrollChangedListener = onScrollChangedListener; } public MyScrollView(Context context) { super(context); } public MyScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); if(onScrollChangedListener != null){ onScrollChangedListener.scrollSomething(); } } //定義滾動變化上的回撥介面 public interface OnScrollChangedListener{ public void scrollSomething(); } }
美團詳情的activity
package mm.shandong.com.testmtxqcomplex; import android.animation.ValueAnimator; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.view.ViewTreeObserver; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import mm.shandong.com.testmtxqcomplex.myui.MyScrollView; public class TestMTXQComplexActivity extends AppCompatActivity { ImageView imageNOFD; ImageView imageFD; FrameLayout frameLayout; MyScrollView scrollView; ImageView imageBannder; int ib_orginalWidth; int ib_orginalHeight; boolean firstMove = true; LinearLayout linearLayout; float touchDownY; boolean isScale = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test_mtxqcomplex); imageNOFD = (ImageView) findViewById(R.id.imageNOFD); imageFD = (ImageView) findViewById(R.id.imageFD); frameLayout = (FrameLayout) findViewById(R.id.frameLayout); imageBannder = (ImageView) findViewById(R.id.imageBannder); linearLayout = (LinearLayout) findViewById(R.id.linearlayout); ///frameLayout建立完成之後呼叫該方法,因為建立之前得不到控制元件高度和寬度 frameLayout.getViewTreeObserver().addOnGlobalLayoutListener( new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { ///初始化imageBannder位置,和浮動圖片位置 int y1_position = imageBannder.getHeight(); linearLayout.layout(0, y1_position,linearLayout.getWidth(), y1_position + linearLayout.getHeight()); int y_position = (int) imageNOFD.getY() + y1_position; imageFD.layout(0, y_position, imageFD.getWidth(), y_position + imageFD.getHeight()); ib_orginalHeight = imageBannder.getHeight(); ib_orginalWidth = imageBannder.getWidth(); } }); scrollView = (MyScrollView) findViewById(R.id.scrollView); ///滾動條滾動時,註冊滾動變化的監聽事件,重新設定imageBannder位置和浮動圖片位置 scrollView.setOnScrollChangedListener(new MyScrollView.OnScrollChangedListener() { @Override public void scrollSomething() { imageBannder.layout(0, scrollView.getScrollY() / 2, imageBannder.getWidth(), scrollView.getScrollY() / 2 + imageBannder.getHeight()); int y_position = (int) Math.max(scrollView.getScrollY(), linearLayout.getY() + imageNOFD.getY()); imageFD.layout(0, y_position, imageFD.getWidth(), y_position + imageFD.getHeight()); } }); ///註冊手指觸控移動的事件監聽 scrollView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { int motionAction = motionEvent.getAction(); switch (motionAction) { case MotionEvent.ACTION_DOWN: //記錄第一次按下的位置 touchDownY = motionEvent.getY(); //如果手指按下時,srollY不等於零則不能放大圖片,等於零是放大圖片的必要條件 if (scrollView.getScrollY() != 0) { isScale = false; } break; case MotionEvent.ACTION_UP: if (isScale) { //判斷手指第一次是向上滑動還是向下滑動 if (motionEvent.getY() - touchDownY > 0) { ///定義手指鬆開時的圖片動畫 final ValueAnimator va = ValueAnimator.ofFloat(motionEvent.getY(), touchDownY); va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { float currentY = (float) va.getAnimatedValue(); float moveDistance = (currentY - touchDownY) * 0.3f; int tempheight = (int) (ib_orginalHeight + moveDistance); int tempwidth = (int) (tempheight * ((float) ib_orginalWidth / ib_orginalHeight)); int x_position = (int) ((ib_orginalWidth - tempwidth) / 2); imageBannder.layout(x_position, 0, x_position + tempwidth, tempheight); linearLayout.layout(0, tempheight, linearLayout.getWidth(), tempheight + linearLayout.getHeight()); imageFD.layout(0, tempheight, imageFD.getWidth(), tempheight + imageFD.getHeight()); } }); va.setDuration(200); va.start(); } } firstMove = true; isScale = true; break; case MotionEvent.ACTION_MOVE: //手指當前位置與第一次按下時的距離 float distance = motionEvent.getY() - touchDownY; if (isScale) { if (firstMove) { //根據手指第一次移動判斷移動方向是向上還是向下,向下放大圖片 if (distance > 0) { isScale = true; firstMove = false; } else if (distance < 0) { isScale = false; firstMove = false; } } } if (isScale) { if (distance > 0) { //如果手指按下時滾動條的scrollY屬性為0,並且向下滾動,那麼放大圖片 float moveDistance = distance * 0.3f; int tempheight = (int) (ib_orginalHeight + moveDistance); int tempwidth = (int) (tempheight * ((float) ib_orginalWidth / ib_orginalHeight)); int x_position = (int) ((ib_orginalWidth - tempwidth) / 2); imageBannder.layout(x_position, 0, x_position + tempwidth,tempheight); linearLayout.layout(0, tempheight, linearLayout.getWidth(), tempheight + linearLayout.getHeight()); imageFD.layout(0, tempheight, imageFD.getWidth(), tempheight + imageFD.getHeight()); } return true; } } return false; } }); } }
</pre><pre name="code" class="java">佈局檔案
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <mm.shandong.com.testmtxqcomplex.myui.MyScrollView android:id="@+id/scrollView" android:layout_width="match_parent" android:layout_height="match_parent"> <FrameLayout android:id="@+id/frameLayout" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/imageBannder" android:layout_width="match_parent" android:layout_height="130dp" android:scaleType="centerCrop" android:src="@drawable/banner" /> <LinearLayout android:id="@+id/linearlayout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ImageView android:id="@+id/imageNOFD" android:layout_width="match_parent" android:layout_height="wrap_content" android:scaleType="centerCrop" android:src="@drawable/fd" /> <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:scaleType="centerCrop" android:src="@drawable/meituan1" /> <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:scaleType="centerCrop" android:src="@drawable/meituan1" /> <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:scaleType="centerCrop" android:src="@drawable/meituan1" /> <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:scaleType="centerCrop" android:src="@drawable/meituan1" /> </LinearLayout> <ImageView android:id="@+id/imageFD" android:layout_width="match_parent" android:layout_height="wrap_content" android:scaleType="centerCrop" android:src="@drawable/fd" /> </FrameLayout> </mm.shandong.com.testmtxqcomplex.myui.MyScrollView> </LinearLayout>
</pre><pre code_snippet_id="1892699" snippet_file_name="blog_20160921_4_3682959" name="code" class="java">
以上是全部程式碼。最後介紹一款本人開發幫助初學者的app android學習手冊,它包含三個部分,分別是例項、原始碼和文件。
通過例項demo讓安卓學習的童鞋對學的是什麼有一個最直接、最感官的認識。通過檢視原始碼,能快速把別人的知識轉化成自己的。通過文件對知識點進行最全面的學習。例子都是最簡單,最全面的,沒有無用程式碼,介紹哪一章就突出本章內容,
相信大家都能看懂學會。安卓無憂的程式碼部分採用android studio的目錄結構,程式碼全部高亮顯示,多種主題供讀者選擇,
原始碼部分的圖片均可以開啟檢視。每一章都詳細介紹讓初學者不僅知其然還知其所以然,文件也有三種主題可選,
文件中的小圖均可以點選放大檢視。最後附原始碼地址以及android學習手冊108例子例子原始碼 。