Android加速度傳感器實現(xiàn)鐘擺效果 類似于Houzz飄帶界面

先看效果圖:飄帶會隨著手機的旋轉進行飄動


飄帶.gif

代碼量比較少,所有就都寫一塊啦,哈哈!直接貼代碼了,說明直接看注釋就OK。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.yubaokang.houzz_viewtaganim.MainActivity">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@mipmap/bg"/>
</RelativeLayout>
/**
 * 錨點對象
 * Created by Hank on 2016/4/22.
 */
public class MarkDataList {

    private int id;
    private int x;
    private int y;

    public MarkDataList(int id, int x, int y) {
        this.id = id;
        this.x = x;
        this.y = y;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }
}
/**
 * https://gitlab.com/yubaokang/Houzz_ViewTagAnim
 * 動態(tài)添加view,根據(jù)加速度傳感器旋轉,擺動,類似于Houzz app的飄帶動畫
 */
public class MainActivity extends AppCompatActivity implements SensorEventListener {

    private RelativeLayout container;
    private List<ImageView> imageViewList;

    long lastTime;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        container = (RelativeLayout) findViewById(R.id.container);
        imageViewList = new ArrayList<>();
        initSensor();
        lastTime = System.currentTimeMillis();
    }


    @Override
    protected void onResume() {
        super.onResume();
        addView(container, getDatas());
    }

    /**
     * 初始化數(shù)據(jù)-模擬
     *
     * @return
     */
    public List<MarkDataList> getDatas() {
        List<MarkDataList> datas = new ArrayList<>();
        datas.add(new MarkDataList(1, 100, 100));
        datas.add(new MarkDataList(2, 200, 200));
        datas.add(new MarkDataList(3, 300, 300));
        return datas;
    }

    private SensorManager sensorMgr;
    private Sensor localSensor;

    //初始化傳感器
    public void initSensor() {
        sensorMgr = ((SensorManager) getSystemService(Context.SENSOR_SERVICE));
        localSensor = sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        //這里最后一個參數(shù)(SensorManager.SENSOR_DELAY_FASTEST)可以修改成SENSOR_DELAY_NORMAL或者其他的來調整傳感器靈敏度,
        // 然后去掉onSensorChanged()方法中thisTime和lastTime的時間差判斷,
        sensorMgr.registerListener(this, localSensor, SensorManager.SENSOR_DELAY_FASTEST);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        sensorMgr.unregisterListener(this, localSensor);//接觸綁定傳感器監(jiān)聽
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        long thisTime = System.currentTimeMillis();
        //改變傳感器靈敏度,可以把這里的時間差判斷去掉
        if (thisTime - lastTime > 200) {
            lastTime = thisTime;
            float x = event.values[0];
            float y = event.values[1];
            float z = event.values[2];
            anim(x, y);
        }
    }

    public void addView(RelativeLayout container, List<MarkDataList> markDataLists) {
        int tagWidth = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_material_tag).getWidth();
        int containerWidth = 1080;//父布局寬度
        int containerHeight = 1920;//父布局高度
        float scaleX = (containerWidth / 330.0F);//MarkDataList中的x坐標是根據(jù)330F個像素進行標記的
        float scaleY = (containerHeight / 585.0F);//MarkDataList中的y坐標是根據(jù)585個像素進行標記的
        for (final MarkDataList anchorData : markDataLists) {
            ImageView localImageView = new ImageView(this);
            localImageView.setBackgroundResource(R.mipmap.ic_material_tag);
            localImageView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(MainActivity.this, "點擊了飄帶" + anchorData.getId(), Toast.LENGTH_SHORT).show();
                }
            });
            imageViewList.add(localImageView);
            RelativeLayout.LayoutParams localLayoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            localLayoutParams.setMargins((int) (anchorData.getX() * scaleX) - tagWidth / 2, (int) (anchorData.getY() * scaleY), 0, 0);
            container.addView(localImageView, localLayoutParams);
        }
    }

    private float xOld;
    private float yOld;

    //左右各180度
    public void anim(float x, float y) {
        for (ImageView imageView : imageViewList) {
            imageView.startAnimation(getAnim(xOld, yOld, x, y));
        }
        xOld = x;
        yOld = y;
    }

    private RotateAnimation getAnim(float xOld, float yOld, float x, float y) {
        RotateAnimation localRotateAnimation = new RotateAnimation(getRotate(xOld, yOld), getRotate(x, y), Animation.RELATIVE_TO_SELF, 0.5F, Animation.RELATIVE_TO_SELF, 0.2F);
        localRotateAnimation.setDuration(1000);
        localRotateAnimation.setFillAfter(true);//動畫執(zhí)行完后是否停留在執(zhí)行完的狀態(tài)
        localRotateAnimation.setInterpolator(new OvershootInterpolator());
        return localRotateAnimation;
    }

    /**
     * 根據(jù)加速度傳感器的旋轉方向x,y,計算得到旋轉角度,包含正負,正負代表旋轉的方向
     *
     * @param x
     * @param y
     * @return
     */
    public float getRotate(float x, float y) {
        float rotate = 0;
        if (x <= 0) {
            if (y > 0) {
                rotate = 9 * x;
            } else {
                rotate = -9 * (9 - y);
            }
        } else {
            if (y >= 0) {
                rotate = 9 * x;
            } else {
                rotate = 9 * (9 - y);
            }
        }
        return rotate;
    }
}

項目地址
https://gitlab.com/yubaokang/Houzz_ViewTagAnim

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,368評論 25 708
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,948評論 18 139
  • 最近因為體檢報告說身體已經(jīng)因為熬夜開始透支,后調整作息,跑步,又因為發(fā)燒感冒,每天都渾身乏力,渾渾噩噩,遂停止了寫...
    小夙Sky閱讀 172評論 0 0
  • 沒有聽見房東家的狗的聲音?,F(xiàn)在園子里非常靜。那棵不知名的五瓣的白色小花仍然寂寞地開著。陽光照在松枝和盆中的花樹上,...
    簡書茶館葉老板閱讀 2,571評論 1 18
  • 我覺得你應該還是沒有睡覺吧,下午6點睡到9點,怎么會困呢,無非就是想找個理由不想理我了。 我承認,今天我又小心眼了...
    遇見久伴閱讀 163評論 0 0