Android的listactivity加速度计滚动发行 [英] Android listactivity scrolling with accelerometer issue

查看:165
本文介绍了Android的listactivity加速度计滚动发行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的Andr​​oid应用程序ListActivity完美的作品。
直到我决定通过使用加速计来添加滚动功能。

I have a ListActivity in my android application that works perfectly. Until I decided to add scrolling capabilities by using the accelerometer.

下面是我的code:

package be.pxl.minecraftguide;

import android.app.ListActivity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.support.v4.widget.SimpleCursorAdapter;
import android.widget.ListView;
import be.pxl.minecraftguide.providers.RecipeCategoryProvider;

public class Crafting extends ListActivity implements SensorEventListener {
    private SimpleCursorAdapter adapter;
    private SensorManager sensorManager;
    private Sensor acceleroMeter;
    private float[] history = new float[2];

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);     
        setContentView(R.layout.categorylist);

        ContentResolver cr = getContentResolver();
        Cursor cursor = cr.query(RecipeCategoryProvider.CONTENT_URI, null, null, null, null);
        String[] from = {RecipeCategoryProvider.COL_CATID, RecipeCategoryProvider.COL_CATIMG, RecipeCategoryProvider.COL_CATDESC};
        int[] to = { R.id.txtCatID, R.id.imgCatImage, R.id.txtCatDescription };
        adapter = new SimpleCursorAdapter(getApplicationContext(), R.layout.categoryrow, cursor, from, to, 0);
        /*SimpleCursorAdapter.ViewBinder viewBinder = new SimpleCursorAdapter.ViewBinder() {

            @Override
            public boolean setViewValue(View view, Cursor cursor, int arg2) {
                if(view.getId() == R.id.imgCatImage) {
                    ImageView image = (ImageView)findViewById(R.id.imgCatImage);
                    image.setImageResource(R.drawable.ic_launcher);
                }

                return false;
            }

        };*/

        setListAdapter(adapter);

        //__________BRON/ http://stackoverflow.com/questions/18751878/android-using-the-accelerometer-to-create-a-simple-maraca-app_____________

        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        acceleroMeter = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        sensorManager.registerListener(this, acceleroMeter, 1000000);

        /*recipeListView.setOnClickListener(new OnItemClickListener(){
            public void onItemClick(AdapterView<?> parent, View row,
                    int position, long id) {

                    TextView txtId = (TextView)row.findViewById(R.id.txtRecipeID);
                    int recipeID = Integer.parseInt(txtId.getText().toString());
                    String description = ((TextView)row.findViewById(R.id.txtRecipeDescription)).getText().toString();


                    // Launching new Activity on selecting single List Item
                    // Intent craftingDetailIntent = new Intent(getApplicationContext(), craftingdetail.class);
                    // sending data to new activity
                    //craftingDetailIntent.putExtra("Category", item);
                    //startActivity(craftingDetailIntent); 
                }
        });*/
    }

    /*@Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        // TODO Auto-generated method stub
        super.onListItemClick(l, v, position, id);

        int recipeID = Integer.parseInt(v.getTag().toString());
    }*/

    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        sensorManager.unregisterListener(this); //De accelerometer afzetten
    }

    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        sensorManager.registerListener(this, acceleroMeter, SensorManager.SENSOR_DELAY_UI); //De accelerometer opnieuw starten
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            float xChange = history[0] - event.values[0];
            float yChange = history[1] - event.values[1]; //Verschil tussen nieuwe en oude positie ophalen.

            history[0] = event.values[0];
            history[1] = event.values[1]; //Nieuwe waarden bewaren voor volgende event trigger

            if (xChange > 2){
                //Links
            }
            else if (xChange < -2){
                //Rechts
            }

            if (yChange > 2){
                    getListView().smoothScrollBy(getListView().getHeight() * adapter.getCount(), 2000);
                    getListView().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            getListView().smoothScrollBy(0, 0); //Geanimeerd scrollen naar laatste positie
                            getListView().setSelection(adapter.getCount() - 1);
                        }
                    }, 1000);
            }
            else if (yChange < -2){
                getListView().smoothScrollBy(getListView().getHeight() * adapter.getCount(), 2000);
                getListView().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        getListView().smoothScrollBy(0, 0); //Geanimeerd scrollen naar eerste positie positie
                        getListView().setSelection(0);
                    }
                }, 1000);
            }
        }

    }


}

问题是,当我提出一个向上运动,清单应在底部向下滚动的广告服务。但我的列表滚动下来,然后备份偶尔。也是一样的向下运动。

The problem is, when I make an upward movement, the list should scroll down ad stay at the bottom. But my list scrolls down and then back up occasionally. Same goes for downward movements.

<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/list"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/minecraft_portrait"
    android:transcriptMode="alwaysScroll" >


</ListView>

而不是真正相关的,但这里是我行XML

And not really relevant, but here's my row xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/recipeRow"
    android:layout_width="match_parent"
    android:layout_height="65sp"
    android:background="@drawable/listview_selector" >

    <TextView
        android:id="@+id/txtCatID"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dp"
        android:layout_marginTop="5dp"
        android:textColor="@android:color/black" />

    <ImageView
        android:id="@+id/imgCatImage"
        android:layout_width="wrap_content"
        android:layout_height="55sp"
        android:layout_centerVertical="true"
        android:layout_alignParentLeft="true"
        android:src="@drawable/ic_launcher"
        android:contentDescription="@string/recipecategory" />

    <TextView
        android:id="@+id/txtCatDescription"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_toRightOf="@id/imgCatImage"
        android:gravity="center"
        android:background="#99FFFFFF"
        android:textSize="20sp"
        android:textColor="@android:color/black"
        android:text="test" />

</RelativeLayout>

我该如何解决这个问题?

How can I fix this?

推荐答案

我一直在寻找的滚动利用传感器(在谷歌玻璃的上下文中)一个ListActivity相同的解决方案,而对方的回答并没有为我工作(滚动飘忽不定)。

I was looking for the same solution for scrolling a ListActivity using sensors (in context of Google Glass), and the other answer didn't work for me (scrolling was erratic).

我能得到另一个版本虽然工作,根据刚上的ListView mList ,在本例下面)。注意,这还假定在屏幕上的项目的一个固定数目的时间(因为所有玻璃显示的大小相同),但是这可以被改变为检查有多少项目是在屏幕上更一般的Andr​​oid溶液。该解决方案还采用了 Sensor.TYPE_ROTATION_VECTOR ,它不支持的设备上的一些传感器融合,因此具有更少的噪音输出(从而减少不必要的向上/向下运动)。

I was able to get another version working though, based just on the ListView (mList, in the example below). Note that this also assumes a fixed number of items on the screen at one time (since all Glass displays are the same size), but this could be changed to check how many items are on the screen for a more general Android solution. This solution also uses the Sensor.TYPE_ROTATION_VECTOR, which does some sensor fusion on supported devices, and therefore has a less noisy output (resulting in less unwanted up/down movement).

注册监听器:

mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
    mSensorManager.registerListener(this,
        mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR),
        SensorManager.SENSOR_DELAY_UI);

...这是在 onSensorChanged()方法:

@Override
public void onSensorChanged(SensorEvent event) {
    if (mList == null) {
        return;
    }

    if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {
        SensorManager.getRotationMatrixFromVector(mRotationMatrix, event.values);

        // Only uncomment the below two lines if you're running on Google Glass
        //SensorManager.remapCoordinateSystem(mRotationMatrix, SensorManager.AXIS_X,
        //    SensorManager.AXIS_Z, mRotationMatrix);
        SensorManager.getOrientation(mRotationMatrix, mOrientation);

        mHeading = (float) Math.toDegrees(mOrientation[0]);
        mPitch = (float) Math.toDegrees(mOrientation[1]);

        float xDelta = history[0] - mHeading;  // Currently unused
        float yDelta = history[1] - mPitch;

        history[0] = mHeading;
        history[1] = mPitch;

        float Y_DELTA_THRESHOLD = 0.10f;

        //Log.d(TAG, "Y Delta = " + yDelta);

        int scrollHeight = mList.getHeight()
            / 19; // 4 items per page, scroll almost 1/5 an item

        //Log.d(TAG, "ScrollHeight = " + scrollHeight);

        if (yDelta > Y_DELTA_THRESHOLD) {
            //Log.d(TAG, "Detected change in pitch up...");
            mList.smoothScrollBy(-scrollHeight, 0);
        } else if (yDelta < -Y_DELTA_THRESHOLD) {
            //Log.d(TAG, "Detected change in pitch down...");
            mList.smoothScrollBy(scrollHeight, 0);
        }
    }
}

更多详细信息,这样的回答:
http://stackoverflow.com/a/23298377/937715

有关code,它重新映射传感器坐标系来处理在Android设备上所有可能的方向变化,请参阅:
http://stackoverflow.com/a/22138449/937715

For code that remaps the sensor coordinate system to handle all possible orientation changes on Android devices, see: http://stackoverflow.com/a/22138449/937715

这篇关于Android的listactivity加速度计滚动发行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆