안 드 로 이 드(Android)3DTouch 효과 구현

10429 단어 android3DTouch
이 블 로그 에서 할 효과 도:

저 품질 동 도 를 보 여 주세요.

이 움 직 이 는 그림 은 효과 가 좋 지 않 습 니 다.실제로 퍼 지 는 효 과 는 위의 첫 번 째 그림 과 같 을 것 입 니 다.뒤에 코드 가 나 올 것 입 니 다.관심 이 있 으 면 실행 해 보 세 요. 
먼저 생각 을 말 해 보 자.우리 가 이 효 과 를 실현 하려 면 사실은 몇 가지 만 파악 해 야 한다.
      1.화면 캡 처
      2.모호 가우스 모호)
      3.보기 추가
      4.애니메이션 팝 업
      5.사건 처리 장
      6.최적화(모호 속도 와 강도)
프로 세 스:사용자 가 하나Item를 누 를 때 우 리 는 먼저 현재 화면의 그림 을 캡 처 한 다음 에 이 그림 을 압축 한 다음 에 고 스 퍼 지 를 한 다음 에 전체 레이아웃 위 에 덮어 쓰 면 인터페이스 가 모호 한 효과 가 나 옵 니 다.이 어 우리 가 동적 으로 인터페이스 에CardView를 추가 하여 우리 의Item구 조 를 보 여 줍 니 다.이것CardView은 우리 가 클릭 한 대응 하 는 Item 에 나타 날 것 입 니 다.마지막 으로 3D Touch 팝 업 에 대응 하 는 애니메이션 을 추가 하면 됩 니 다. 
다음 에 우 리 는 한 걸음 한 걸음 전체 절 차 를 완성 한다.
① 화면 캡 처
이 부분 은 상대 적 으로 간단 하 다.왜냐하면 우 리 는 현재 화면 에 표 시 된 내용Bitmap을 얻 으 려 면 기 존의 방법 이 있 고 코드 는 다음 과 같다.

  private Bitmap getScreenImage() { //          
    View view = root;
    view.setBackgroundColor(Color.WHITE);
    view.setDrawingCacheEnabled(true);
    view.buildDrawingCache();
    Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache(), 0, 0, view.getWidth(), view
        .getHeight());
    view.destroyDrawingCache();
    return bitmap;
  }
먼저 레이아웃 을 말씀 드 리 겠 습 니 다.여기 레이아웃 파일 은 다음 과 같 습 니 다.

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:id="@+id/activity_main"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context="com.fndroid.threedtouchdemo.MainActivity">

  <LinearLayout
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
      android:id="@+id/toolbar"
      android:layout_width="match_parent"
      android:layout_height="?attr/actionBarSize"
      android:background="@color/colorPrimary"
      app:title="@string/app_name"
      app:titleTextColor="#fff"/>

    <ListView
      android:id="@+id/lv"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      tools:listitem="@layout/item"/>
  </LinearLayout>

  <ImageView
    android:id="@+id/cover"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

  <android.support.v7.widget.CardView
    android:id="@+id/cv"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:translationZ="5dp"
    app:cardCornerRadius="10dp"/>

</FrameLayout>
우리 의 가장 바깥쪽 에 하나의FrameLayout를 사용 한 것 을 볼 수 있다.그 이 유 는 우리 가 전체 구조 에 고 스 의 모호 한 캡 처 를 덮어 야 하기 때문이다.맨 아래ImageView는 모호 한 효 과 를 내 는 것 을 볼 수 있다.처음에 우 리 는 그것ImageAlpha을 0 으로 설정 하여 투명 하 게 하면 된다.맨 아래CardView는 팝 업 컨트롤 입 니 다.이 건 잠시 후에 말씀 드 리 겠 습 니 다.우리 가 캡 처 한rootFrameLayout아래LinearLayout이다.왜냐하면 우 리 는ToolBar도 모호 하 게 해 야 하기 때문이다. 
② 가우스 모호
이것 은 나의 이전 블 로그 인 동적 고 스 모호 어떻게 하 는 지 에서 이미 말 했 으 니 참고 할 수 있 습 니 다.이것 은 해당 하 는 코드 를 제시 합 니 다.

  private Bitmap blur(Bitmap bitmap, float radius) {
    Bitmap output = Bitmap.createBitmap(bitmap); //       
    RenderScript rs = RenderScript.create(this); //     RenderScript  
    ScriptIntrinsicBlur gaussianBlue = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); //
    //         
    Allocation allIn = Allocation.createFromBitmap(rs, bitmap); //       
    Allocation allOut = Allocation.createFromBitmap(rs, output); //       
    gaussianBlue.setRadius(radius); //       ,  0f<radius<=25f
    gaussianBlue.setInput(allIn); //       
    gaussianBlue.forEach(allOut); //     ,          
    allOut.copyTo(output); //         Bitmap,        
    rs.destroy(); //   RenderScript  ,API>=23   rs.releaseAllContexts()
    return output;
  }
모듈 에 대응 하 는 build.gradle 파일 설정:

  defaultConfig {
    ...
    renderscriptTargetApi 18
    renderscriptSupportModeEnabled true
  }
 ③ 팝 업 보기
이 보 기 는ItemViewCardView에 추가 하고CardView의 위 치 를 대응Item위치 에 두 어야 합 니 다.

  //        
  private void showView(int position, View view){
    newView = LayoutInflater.from(this).inflate(R.layout.item, null); //   Itme   
    TextView tv = (TextView) newView.findViewById(R.id.item_tv); //       
    tv.setText(data.get(position).get("name")); //  Item          
    newView.setBackgroundColor(Color.WHITE);
    //        ,    margintop   
    FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(view.getWidth() - 30, view.getHeight());
    params.topMargin = (int) (view.getY() + mToolbar.getHeight()); //    marginTop   item Y  toolbar   
    params.leftMargin = 15;
    params.rightMargin = 15;
    mCardView.setVisibility(View.VISIBLE);
    mCardView.setLayoutParams(params);
    mCardView.addView(newView, view.getLayoutParams()); //  View   CardView,      item  
    startAnimate(mCardView); //     
  }
여기 서itemviewCardView에 직접 불 러 올 수 없습니다.itemView는 이미 아버지 가 배치 되 어 이상 하 게 던 질 수 있 기 때 문 입 니 다.해결 방법 은 레이아웃 에 따라 하 나 를 다시 매 핑 한 다음 데 이 터 를 채 워 넣 는 것 이다.이 어 카드 의 위치 정보 와 크기 정 보 를 설정 합 니 다.카드 가 대응 하 는Item위 에 표시 되 어야 하기 때 문 입 니 다. 
④ 애니메이션 팝 업
이것 은 비교적 간단 한 부분 입 니 다.우 리 는 직접PropertyValuesHolder을 사용 하여 팝 업 과 수축 의 동작 을 합 니 다.왜냐하면 우 리 는 X 와 Y 를 동시에 확대 해 야 하기 때 문 입 니 다.물론 다른 방법 으로 도 사용 할 수 있 습 니 다.코드 는 다음 과 같 습 니 다.

  private void startAnimate(CardView cardView) {
    PropertyValuesHolder pyhScaleX = PropertyValuesHolder.ofFloat("scaleX", 0.1f, 1.05f);
    PropertyValuesHolder pyhScaleY = PropertyValuesHolder.ofFloat("scaleY", 0.1f, 1.05f);
    ObjectAnimator animator_out = ObjectAnimator.ofPropertyValuesHolder(mCardView, pyhScaleX,
        pyhScaleY); //     X Y
    animator_out.setInterpolator(new AccelerateDecelerateInterpolator());
    animator_out.setDuration(350);
    PropertyValuesHolder pyhScaleX2 = PropertyValuesHolder.ofFloat("scaleX", 1.05f, 1f);
    PropertyValuesHolder pyhScaleY2 = PropertyValuesHolder.ofFloat("scaleY", 1.05f, 1f);
    ObjectAnimator animator_in = ObjectAnimator.ofPropertyValuesHolder(mCardView, pyhScaleX2,
        pyhScaleY2);
    animator_in.setInterpolator(new AccelerateDecelerateInterpolator());
    animator_in.setDuration(100);

    AnimatorSet animatorSet = new AnimatorSet();
    animatorSet.playSequentially(animator_out, animator_in); //          
    animatorSet.start();
  }
⑤ 감청 장 은 사건 별로
여 기 는ListView만 사용 하여 이 내용 을 간소화 하고 기 존 감청 기 를 통 해 직접 실현 할 수 있 기 때문이다.

@Override
  public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
    mCover.setImageBitmap(blur(blur(getScreenImage(), 25f),25f)); //             
    mCover.setVisibility(View.VISIBLE);
    mCover.setImageAlpha(0);
    new Thread(new Runnable() {
      int progress = 50;

      @Override
      public void run() {
        while (progress < 255) {
          try {
            Thread.sleep(1);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          Message msg = new Message();
          msg.obj = progress++;
          mHandler.sendMessage(msg);
        }
      }
    }).start();
    showView(position, view);
    return true;
  }
이곳 의 세 번 째 줄 에 서 는 두 번blur방법 으로 그림 을 가우스 모호 하 게 만 들 었 다.만약 에 지난 블 로 그 를 보면 매번 가우스 의 모호 한 최대 모호 반경 은 25 이 고 iOS 에 도 모호 한 효 과 를 내 려 면 25 가 부족 하기 때문에 모호 한 그림 을 한 번 더 모호 하 게 만 들 수 있다.대비 도(왼쪽 은 2 번 모호 하고 오른쪽 은 1 번):
   
 ⑥ 최적화
그러나 실제로 해상도 가 높 은 휴대 전화 에 대해 서 는 화면 해상도 가 높 은 경우 여러 번 모호 하 게 하 는 것 도 추천 하지 않 는 다.여기 서 우리 가 먼저 캡 처 를 얻 은 다음 에 이 캡 처 한 그림 을 먼저 압축 할 수 있 는 지 생각해 볼 수 있다.후기 에 모호 해 야 하기 때문이다.즉,이 그림 이 압축 된 것 은 우리 가 모호 하 게 하 는 데 영향 을 주지 않 는 다(마지막 까지 모호 하기 때문이다).실제로 우리 가 그림 을 압축 한 후에 같은 모호 한 반지름 에서 그림 의 모호 한 효과 가 다르다 는 것 을 발견 할 수 있다.다음 과 같은 두 그림 이다.
   
이 유 는 고 스 가 모호 하 게 사용 하 는 알고리즘 에서 한 점 의 색 채 를 확정 하 는 것 은 이 점 부근의 다른 점 을 통 해 평균(띠 권)을 구 하 는 것 이 고 근처에 있 는 것 은 대부분이 픽 셀 점 이 며 모호 한 반지름 을 통 해 확정 하 는 것 이다.그림 이 압축 된 후 같은 모호 반경 아래 에서 매번 표본 을 추출 하 는 구역 이 커지 기 때문에 모호 강도 가 더욱 커진다.
이렇게 하면 우 리 는 여러 번 모호 하지 않 아 도 되 고 그림 을 압축 한 후에 총 픽 셀 점 이 적어 지고 모호 속도 도 빨 라 질 수 있다.
그림 압축 코드 를 보 여 줍 니 다.

  private Bitmap getSmallSizeBitmap(Bitmap source, float percent) {
    if (percent > 1 || percent <= 0) {
      throw new IllegalArgumentException("percent must be > 1 and <= 0");
    }
    Matrix matrix = new Matrix();
    matrix.setScale(percent, percent);
    return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
  }
총결산
이상 은 안 드 로 이 드(Android)에서 3DTouch 효 과 를 실현 하 는 모든 내용 입 니 다.방금 관심 이 있 는 것 은 스스로 실천 할 수 있 습 니 다.본 논문 의 내용 이 여러분 에 게 도움 이 되 기 를 바 랍 니 다.

좋은 웹페이지 즐겨찾기