Android仿微信圖片點擊全屏效果_Android

來源:互聯網
上載者:User

廢話不多說,先看下效果:

先是微信的

再是模仿的

先說下實現原理,再一步步分析

這裡總共有2個Activity一個就是首頁,一個就是顯示我們圖片效果的頁面,參數通過Intent傳送,素材內容均來自網路,(感謝聰明的蘑菇) 圖片都是Glide非同步下的,下的,下的重要的事情說三次,然後就是用動畫做放大操作然後顯示出來了(並沒有做下載原圖的實現,反正也是一樣 下載下來Set上去而且動畫都不需要更簡便)。

OK,我們來看分析下

obj,目錄下分別建立了2個對象,一個用來使用來處理顯示頁面的圖片尺寸資訊以及位置資訊,還有一個是用來附帶URL和解析度

Config這個類就是我們的URL了沒其他什麼內容。

我們一個一個頁面來看,先看MainActivity

他做的事情很簡單,就是把下個頁面的一些資訊初始化一下然後通過Intent傳過去,本身不做什麼多餘操作

package wjj.com.imitatewechatimage.activity;import android.content.Intent;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.ImageView;import wjj.com.imitatewechatimage.R;import com.apkfuns.logutils.LogUtils;import com.bumptech.glide.Glide;import wjj.com.imitatewechatimage.Config;import wjj.com.imitatewechatimage.obj.ImageInfoObj;import wjj.com.imitatewechatimage.obj.ImageWidgetInfoObj;public class MainActivity extends AppCompatActivity implements View.OnClickListener {  private ImageView imageView;  private ImageInfoObj imageInfoObj;  private ImageWidgetInfoObj imageWidgetInfoObj;  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    findId();    init();    Listener();  }  private void findId() {    imageView = (ImageView) findViewById(R.id.imageView);  }  private void init() {    Glide.with(MainActivity.this).load(Config.IMAGE_URL).placeholder(R.mipmap.maimai).into(imageView);    imageInfoObj = new ImageInfoObj();    imageInfoObj.imageUrl = Config.IMAGE_URL;    imageInfoObj.imageWidth = 1280;    imageInfoObj.imageHeight = 720;    imageWidgetInfoObj = new ImageWidgetInfoObj();    imageWidgetInfoObj.x = imageView.getLeft();    imageWidgetInfoObj.y = imageView.getTop();    imageWidgetInfoObj.width = imageView.getLayoutParams().width;    imageWidgetInfoObj.height = imageView.getLayoutParams().height;  }  private void Listener() {    imageView.setOnClickListener(this);  }  @Override  protected void onResume() {    super.onResume();    LogUtils.d("--->MainActivity onResume");  }  @Override  protected void onPause() {    super.onPause();    LogUtils.d("--->MainActivity onPause");  }  @Override  protected void onDestroy() {    super.onDestroy();    LogUtils.d("--->MainActivity onDestroy");  }  @Override  public void onClick(View v) {    switch (v.getId()) {      case R.id.imageView:        //攜帶參數跳轉        Intent intent = new Intent(MainActivity.this, howImageActivity.class);        intent.putExtra("imageInfoObj", imageInfoObj);        intent.putExtra("imageWidgetInfoObj", imageWidgetInfoObj);        startActivity(intent);        break;      default:        break;    }  }}

具體業務類ShowImageActivity

public class ShowImageActivity extends AppCompatActivity {  private RelativeLayout MainView;  private ImageView showImageView;  private ImageInfoObj imageInfoObj;  private ImageWidgetInfoObj imageWidgetInfoObj;  Button button;  // 螢幕寬度  public float Width;  //原圖高  private float y_img_h;  // 螢幕高度  public float Height;  private float size, size_h, img_w, img_h;  protected float to_x = 0;  protected float to_y = 0;  private float tx;  private float ty;  private final Spring spring = SpringSystem      .create()      .createSpring()      .addListener(new ExampleSpringListener());  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_how_image);    LogUtils.d("--->ShowImageActivity onCreate");    findId();    init();    Listener();  }  private void findId() {    MainView = (RelativeLayout) findViewById(R.id.MainView);    button = (Button) findViewById(R.id.button);  }  private void init() {    DisplayMetrics dm = getResources().getDisplayMetrics();    Width = dm.widthPixels;    Height = dm.heightPixels;    imageInfoObj = (ImageInfoObj) getIntent().getSerializableExtra("imageInfoObj");    imageWidgetInfoObj = (ImageWidgetInfoObj) getIntent().getSerializableExtra("imageWidgetInfoObj");    if (imageInfoObj == null) {      LogUtils.d("--->imageInfoObj==null");    }    if (imageWidgetInfoObj == null) {      LogUtils.d("--->imageWidgetInfoObj==null");    }    showImageView = new ImageView(this);    showImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);    Glide.with(ShowImageActivity.this).load(imageInfoObj.imageUrl).into(showImageView);    img_w = imageWidgetInfoObj.width;    img_h = imageWidgetInfoObj.height - 300;    size = Width / img_w;    y_img_h = imageInfoObj.imageHeight * Width / imageInfoObj.imageWidth;    size_h = y_img_h / img_h;    RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams((int) imageWidgetInfoObj.width,        (int) imageWidgetInfoObj.height);    p.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);    p.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);    showImageView.setLayoutParams(p);    p.setMargins((int) imageWidgetInfoObj.x,        (int) imageWidgetInfoObj.y, (int) (Width - (imageWidgetInfoObj.x + imageWidgetInfoObj.width)),        (int) (Height - (imageWidgetInfoObj.y + imageWidgetInfoObj.height)));    MainView.addView(showImageView);    new Handler().post(new Runnable() {      public void run() {        ShowImageView();      }    });  }  private void Listener() {    showImageView.setOnClickListener(new View.OnClickListener() {      @Override      public void onClick(View v) {        ShowImageView();      }    });    button.setOnClickListener(new View.OnClickListener() {      @Override      public void onClick(View v) {        ShowImageView();      }    });  }  @Override  protected void onResume() {    super.onResume();    LogUtils.d("--->ShowImageActivity onResume");  }  @Override  protected void onPause() {    super.onPause();    LogUtils.d("--->ShowImageActivity onPause");  }  @Override  protected void onDestroy() {    super.onDestroy();    LogUtils.d("--->ShowImageActivity onDestroy");  }  private class ExampleSpringListener implements SpringListener {    @Override    public void onSpringUpdate(Spring spring) {      double CurrentValue = spring.getCurrentValue();      float mappedValue = (float) SpringUtil.mapValueFromRangeToRange(CurrentValue, 0, 1, 1, size);      float mapy = (float) SpringUtil.mapValueFromRangeToRange(CurrentValue, 0, 1, 1, size_h);      showImageView.setScaleX(mappedValue);      showImageView.setScaleY(mapy);      if (CurrentValue == 1) {//        showImageView.setVisibility(View.GONE);      }    }    @Override    public void onSpringAtRest(Spring spring) {    }    @Override    public void onSpringActivate(Spring spring) {    }    @Override    public void onSpringEndStateChange(Spring spring) {    }  }  //實現效果  private void MoveView() {    ObjectAnimator.ofFloat(MainView, "alpha", 0.8f).setDuration(0).start();    MainView.setVisibility(View.VISIBLE);    AnimatorSet set = new AnimatorSet();    set.playTogether(        ObjectAnimator.ofFloat(showImageView, "translationX", tx).setDuration(200),        ObjectAnimator.ofFloat(showImageView, "translationY", ty).setDuration(200),        ObjectAnimator.ofFloat(MainView, "alpha", 1).setDuration(200)    );    set.addListener(new Animator.AnimatorListener() {      @Override      public void onAnimationStart(Animator animator) {      }      @Override      public void onAnimationEnd(Animator animator) {        showImageView.setScaleType(ImageView.ScaleType.FIT_XY);        spring.setEndValue(1);      }      @Override      public void onAnimationCancel(Animator animator) {      }      @Override      public void onAnimationRepeat(Animator animator) {      }    });    set.start();  }  //關閉頁面  private void MoveBackView() {    AnimatorSet set = new AnimatorSet();    set.playTogether(        ObjectAnimator.ofFloat(showImageView, "translationX", to_x).setDuration(200),        ObjectAnimator.ofFloat(showImageView, "translationY", to_y).setDuration(200)    );    set.addListener(new Animator.AnimatorListener() {      @Override      public void onAnimationStart(Animator animator) {      }      @Override      public void onAnimationEnd(Animator animator) {        finish();      }      @Override      public void onAnimationCancel(Animator animator) {      }      @Override      public void onAnimationRepeat(Animator animator) {      }    });    set.start();  }  //具體動畫處理類  private void ShowImageView() {    if (spring.getEndValue() == 0) {      //彈動摩擦力      spring.setSpringConfig(SpringConfig.fromOrigamiTensionAndFriction(300, 5));      //動畫結束後出現的位置      tx = 0;      ty = Height / 2 - (imageWidgetInfoObj.y + img_h + 600);      MoveView();      return;    }    spring.setSpringConfig(SpringConfig.fromOrigamiTensionAndFriction(1, 5));    spring.setEndValue(0);    new Handler().post(new Runnable() {      public void run() {        MoveBackView();      }    });  }  @Override  public boolean onKeyDown(int keyCode, KeyEvent event) {    if (keyCode == KeyEvent.KEYCODE_BACK) {      showImageView.setVisibility(View.VISIBLE);      ShowImageView();    }    return true;  }}

大致流程:
1.在 init()擷取了螢幕資訊,上一個類傳來的參數,以及對座標點進行了一些計算 ,然後用Handler來啟動動畫的效果

2.ShowImageView()處理了動畫的實現,(動畫效果是compile 'com.facebook.rebound:rebound:0.3.8' 實現的,這邊不做教程了給出傳送門:http://facebook.github.io/rebound/)

總結:

總體實現並不是太難,因為有架構的關係,使得複雜的動畫部分不用自己去寫,調用下在回調裡做業務就行,這裡補充下一些過程中用到的技術點

1.圖片的縮放模式:
android:scaleType是控製圖片如何resized/moved來匹對ImageView的size。

ImageView.ScaleType / android:scaleType值的意義區別:

CENTER /center  按圖片的原來size置中顯示,當圖片長/寬超過View的長/寬,則截取圖片的置中部分顯示

CENTER_CROP / centerCrop  按比例擴大圖片的size置中顯示,使得圖片長(寬)等於或大於View的長(寬)

CENTER_INSIDE / centerInside  將圖片的內容完整置中顯示,通過按比例縮小或原來的size使得圖片長/寬等於或小於View的長/寬

FIT_CENTER / fitCenter  把圖片按比例擴大/縮小到View的寬度,置中顯示

FIT_END / fitEnd   把圖片按比例擴大/縮小到View的寬度,顯示在View的下部分位置

FIT_START / fitStart  把圖片按比例擴大/縮小到View的寬度,顯示在View的上部分位置

FIT_XY / fitXY  把圖片不按比例擴大/縮小到View的大小顯示

MATRIX / matrix 用矩陣來繪製,動態縮小放大圖片來顯示。

** 要注意一點,Drawable檔案夾裡面的圖片命名是不能大寫的

2.Layout常用的屬性:

// 相對於給定ID控制項 <a href="http://lib.csdn.net/base/15" class="replace_word" title="undefined" target="_blank" style="color: rgb(223, 52, 52); font-weight: bold;">android</a>:layout_above 將該控制項的底部置於給定ID的控制項之上; android:layout_below 將該控制項的底部置於給定ID的控制項之下; android:layout_toLeftOf 將該控制項的右邊緣與給定ID的控制項左邊緣對齊; android:layout_toRightOf 將該控制項的左邊緣與給定ID的控制項右邊緣對齊;  android:layout_alignBaseline 將該控制項的baseline與給定ID的baseline對齊; android:layout_alignTop 將該控制項的頂部邊緣與給定ID的頂部邊緣對齊; android:layout_alignBottom 將該控制項的底部邊緣與給定ID的底部邊緣對齊; android:layout_alignLeft 將該控制項的左邊緣與給定ID的左邊緣對齊; android:layout_alignRight 將該控制項的右邊緣與給定ID的右邊緣對齊; // 相對於父組件 android:layout_alignParentTop 如果為true,將該控制項的頂部與其父控制項的頂部對齊; android:layout_alignParentBottom 如果為true,將該控制項的底部與其父控制項的底部對齊; android:layout_alignParentLeft 如果為true,將該控制項的左部與其父控制項的左部對齊; android:layout_alignParentRight 如果為true,將該控制項的右部與其父控制項的右部對齊; // 置中 android:layout_centerHorizontal 如果為true,將該控制項的置於水平置中; android:layout_centerVertical 如果為true,將該控制項的置於垂直置中; android:layout_centerInParent 如果為true,將該控制項的置於父控制項的中央; // 指定移動像素 android:layout_marginTop 上位移的值; android:layout_marginBottom 下位移的值; android:layout_marginLeft   左位移的值; android:layout_marginRight   右位移的值; 

這個例子只是例子,部分座標和樣式是寫死的,如果要運用到實際項目中還是要些許就該,在操作的過程中還對載入多圖片進行了測試,暫未發生OOM的情況,補上記憶體使用量情況圖(一直很穩定)

這裡寫圖片描述

代碼地址:https://github.com/ddwhan0123/BlogSample/tree/master/ImitateWeChatImage
源碼下載地址:https://github.com/ddwhan0123/BlogSample/blob/master/ImitateWeChatImage/ImitateWeChatImage.zip?raw=true

以上就是本文的全部內容,希望能夠協助大家實現Android仿微信圖片點擊全屏效果,謝謝大家的閱讀。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.