1

完全に機能する Android アプリケーションに ListActivity があります。加速度計を使用してスクロール機能を追加することを決定するまで。

これが私のコードです:

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);
            }
        }

    }


}

問題は、上に移動すると、リストが下にスクロールして一番下に留まることです。しかし、私のリストは下にスクロールして、時々元に戻ります。下向きの動きも同様です。

<?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があります

<?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>

どうすればこれを修正できますか?

4

2 に答える 2

2

(Google Glass のコンテキストで) センサーを使用して ListActivity をスクロールするための同じソリューションを探していましたが、他の答えはうまくいきませんでした (スクロールは不安定でした)。

ListViewただし、 (以下の例の)だけに基づいて、別のバージョンを機能させることができましたmList。これも、一度に画面に表示されるアイテムの数が一定であることを前提としていますが (Glass ディスプレイはすべて同じサイズであるため)、これを変更して、より一般的な Android ソリューションの画面に表示されるアイテムの数を確認することもできます。このソリューションは、Sensor.TYPE_ROTATION_VECTORサポートされているデバイスでセンサー フュージョンを行う も使用するため、出力のノイズが少なくなります (その結果、望ましくない上下の動きが少なくなります)。

リスナーを登録します。

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);
        }
    }
}

追加の詳細はこの回答にあります: https://stackoverflow.com/a/23298377/937715

センサー座標系を再マッピングして、Android デバイスで可能なすべての向きの変更を処理するコードについては、 https ://stackoverflow.com/a/22138449/937715 を参照してください。

于 2014-04-25T16:34:41.277 に答える