4

アクションバーからアイコンをクリックしたときにアクティビティから呼び出すPreferenceFragmentを使用しようとしていますが、FragmentPreferencesをインテントで呼び出すだけです。

case R.id.settings:
    Intent prefs = new Intent(this, LogicAnalizerPrefs.class);
    startActivity(prefs);
    break;

このように、アイコンをクリックすると、アプリケーションの単純なスタックが発生します。つまり、LogCatの単純なスタックではクラッシュせず、何も奇妙なことはありません。もう一度クリックすると、ANRが表示されます。代わりに使用する場合:

getFragmentManager().beginTransaction().replace(android.R.id.content, new LogicAnalizerPrefs()).commit();

フラグメントは表示されますが、背景は透明です。同じ問題を尋ねるユーザーを見たことがありますが、答えは聖霊降臨祭のインテントを呼び出していますが、アプリケーションがスタックしています。これが私のフラグメントコードです:

public class LogicAnalizerPrefs extends PreferenceFragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.logicanalizerprefs);
    }

}

そして私のlogicanalizerprefs.xml:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >

    <EditTextPreference
        android:defaultValue="128"
        android:key="buffer1"
        android:summary="Buffer canal 1"
        android:title="Buffer" />
    <EditTextPreference
        android:defaultValue="128"
        android:key="buffer2"
        android:summary="Buffer canal 2"
        android:title="Buffer" />
    <EditTextPreference
        android:defaultValue="128"
        android:key="buffer3"
        android:summary="Buffer canal 3"
        android:title="Buffer" />
    <EditTextPreference
        android:defaultValue="128"
        android:key="buffer4"
        android:summary="Buffer canal 4"
        android:title="Buffer" />

</PreferenceScreen>

あなたが私を助けてくれることを願っています私はそれが何であるかわからない:/

--EDIT-- これは、プリファレンスアクティビティ/フラグメントを呼び出しているアクティビティです。これは、achartengineを使用し、実行可能なスレッドを実装して、ハンドラーのグラフを更新します。

public class LogicAnalizerView extends Activity implements Runnable{

    /** Debugging */
    private static final boolean DEBUG = false;     String TAG;
    /** Varios */
    static ActionBar actionBar;         // ActionBar
    static Thread myThread = null;      // Thread para el metodo run() de Runnable
    static boolean Running;             // Ejecuta o no el while dentro de run()
    static Random crazy = new Random(); // Clase Random para generar numeros aleatorios
    /** Tiempo en el eje X */
    static float time = (float) 0.0;    // Tiempo transcurrido (eje X del grafico)
    static final float TimeIncrement = (float) 0.4;     // Tiempo que transcurre por muestreo (duracion de un 1-0)
    static final int XMax = 10;         // Valor maximo de X inicial
    static final int XMin = 0;          // Valor minimo de X inicial
    static int Ticks = 0;               // Veces que el grafico se actualiza
    static final int maxTicks = (int) (XMax/TimeIncrement);     // Cantidad de '1' y '0' que entran en el intervalo [XMin,XMax]
    /** Buffers */
    static int BufferSize;              // Tamaño del buffer de recepcion
    static byte[] ReceptionBuffer;      // Buffer de recepcion
    static byte[] Channel1;             // Buffers para cada canal
    static byte[] Channel2;
    static byte[] Channel3;
    static byte[] Channel4;

    //Lineas en el grafico
    TimeSeries[] input = new TimeSeries[4]; // Cada TimeSeries representa una funcion en el grafico
    XYMultipleSeriesDataset dataset;        // Agrupa todas las TimeSeries en el grafico
    //Renderers
    XYSeriesRenderer renderer;              // Opciones de renderizado para cada TimeSeries
    XYSeriesRenderer renderer1;
    XYSeriesRenderer renderer2;
    XYSeriesRenderer renderer3;
    XYMultipleSeriesRenderer mRenderer;     // Agrupa todas las opciones de renderizado del grafico
    //GraphicalView
    GraphicalView mChartView;               // View del grafico (el grafico en si)

    /**
     * Creacion de la Activity
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        /**
         * ActionBar
         */
        actionBar = getActionBar();                     // Obtengo el ActionBar
        actionBar.setDisplayHomeAsUpEnabled(true);      // El icono de la aplicacion funciona como boton HOME

        /**
         * Preferencias
         */
        SharedPreferences getPrefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
        Channel1 = new byte[Integer.decode(getPrefs.getString("buffer1", "128")) + 1];      // Tamaño de los buffers de cada canal basado en 
        Channel2 = new byte[Integer.decode(getPrefs.getString("buffer2", "128")) + 1];      // la configuracion +1 porque en el buffer[0] se coloca
        Channel3 = new byte[Integer.decode(getPrefs.getString("buffer3", "128")) + 1];      // el tipo de protocolo (I2C, SPI, UART, etc)
        Channel4 = new byte[Integer.decode(getPrefs.getString("buffer4", "128")) + 1];
        ReceptionBuffer = new byte[64];     // Buffer de recepcion general de 64 bytes

        /**
         * Configuro el grafico
         */
        //Crea una "Serie" que es una linea en el grafico llamado "Linea1"
        input[0] = new TimeSeries("Entrada 1");
        input[1] = new TimeSeries("Entrada 2");
        input[2] = new TimeSeries("Entrada 3");
        input[3] = new TimeSeries("Entrada 4");

        //XYMultipleSeriesDataset contiene todas las series, es decir todas las lineas del grafico en esta clase
        dataset = new XYMultipleSeriesDataset();
        dataset.addSeries(input[0]);    // Agregamos la serie que creamos a XYMultipleSeriesDataset que contiene todas las series
        dataset.addSeries(input[1]);
        dataset.addSeries(input[2]);
        dataset.addSeries(input[3]);

        //XYMultipleSeriesRenderer contiene todos los renderer de las diferentes series
        //XYSeriesRenderer le da las propiedades a las Series (lineas) como color y esas cosas
        mRenderer = new XYMultipleSeriesRenderer();
        renderer = new XYSeriesRenderer();
        renderer1 = new XYSeriesRenderer();
        renderer2 = new XYSeriesRenderer();
        renderer3 = new XYSeriesRenderer();

        //Renderers
        mRenderer.addSeriesRenderer(renderer);      // Agrego el XYSeriesRenderer al grupo XYMultipleSeriesRenderer
        mRenderer.addSeriesRenderer(renderer1);
        mRenderer.addSeriesRenderer(renderer2);
        mRenderer.addSeriesRenderer(renderer3);
        mRenderer.setShowGrid(true);                // Muestra una grilla en X e Y en el grafico
        mRenderer.setYTitle("Canales");             // Titulo del eje Y
        mRenderer.setYLabelsAlign(Align.CENTER);    // Alineacion del titulo
        mRenderer.setXTitle("Tiempo x100nS");       // Titulos del eje X
        mRenderer.setXLabelsAlign(Align.CENTER);    // Alineacion del titulo
        mRenderer.setZoomButtonsVisible(true);      // Botones de Zoom visibles
        mRenderer.setZoomEnabled(true, false);      // Zoom sobre el eje X solamente
        mRenderer.setAntialiasing(true);            // Usa antialising para dibujar
        mRenderer.setXAxisMin(XMin);                // Valor minimo del eje X
        mRenderer.setXAxisMax(XMax);                // Valor maximo del eje X

        //Colores de lineas
        renderer.setColor(Color.WHITE);     
        renderer1.setColor(Color.RED);
        renderer2.setColor(Color.GREEN);
        renderer3.setColor(Color.YELLOW);

        //Grosores de lineas
        renderer.setLineWidth(2);
        renderer1.setLineWidth(3);
        renderer2.setLineWidth(4);
        renderer3.setLineWidth(5);

        mChartView = ChartFactory.getLineChartView(this, dataset, mRenderer);
        setContentView(mChartView);

    }

    /**
     * Crea el ActionBar
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        if(DEBUG) Log.i(TAG, "onCreateOptionsMenu() -> LogicAnalizerView");
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.actionbarmain, menu);
        return true;
    }

    /**
     * Listener de los iconos en el ActionBar
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if(DEBUG) Log.i(TAG, "onOptionsItemSelected() -> LogicAnalizerView - Item: " + item.getItemId());

        switch(item.getItemId()){
        case android.R.id.home:
            Intent intent = new Intent(this, MainMenu.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); //si la aplicacion ya esta abierta ir a ella no abrir otra nueva
            startActivity(intent);
        case R.id.settings:
            Intent a = new Intent(this, MainMenu.class);
            a.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(a);
            //Intent prefs = new Intent(getApplicationContext(), LogicAnalizerPrefs.class);
            //startActivity(prefs);
            break;
        case R.id.save:
            createDialog();
            break;
        }
        return true;
    }

    /**
     * Crea una ventana perguntando al usuario el nombre con el que desea guardar la imagen del grafico
     */
    private void createDialog() {
        Running = false;    //Detengo el Thread run()
        AlertDialog.Builder alert = new AlertDialog.Builder(this);
        alert.setTitle("Guardar");
        alert.setMessage("Nombre de archivo");

        // Creamos un EditView para que el usuario escriba
        final EditText input = new EditText(this);
        alert.setView(input);

        // Creamos el boton OK y su onClickListener
        alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                Editable text = input.getText();        // Obtengo el texto que escribio el usuario
                Bitmap bitmap = mChartView.toBitmap();  // Creo un nuevo BitMap

                try {   //Creo un nuevo archivo con el nombre del usuario y extension .jpeg
                    File image = new File(Environment.getExternalStorageDirectory(), "Multi\\" + text.toString() + ".jpeg");
                    if(image.exists()){
                        createDialogConfirm();
                    }
                    FileOutputStream output = new FileOutputStream(image);
                    bitmap.compress(CompressFormat.JPEG, 100, output);
                } catch (FileNotFoundException e) { e.printStackTrace(); }
                Running = true;
            }

        });

        // Boton cancelar
        alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int whichButton) {
              dialog.dismiss();
              Running = true;         
          }
        });
        alert.show();
    }

    private boolean createDialogConfirm() {
        AlertDialog.Builder confirm = new AlertDialog.Builder(this);
        confirm.setTitle("Guardar");
        confirm.setMessage("El archivo existe, sobreescribir ?");

        // Boton cancelar
        confirm.setPositiveButton("Si", new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int whichButton) {      
          }
        });

        // Boton cancelar
        confirm.setNegativeButton("No", new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int whichButton) {
              dialog.dismiss();   
          }
        });

        confirm.show();
        return true;
    }

    /**
     * Prueba de byte
     * @param a: byte para testear
     * @param bit: numero de bit a testear 0-7
     */
    public boolean bitTest (byte a, int bit) {
        return (a & (1 << bit)) != 0;
    }

    /**
     * @author Andres
     * Se llama al crear la Activity y al volver a ella si se ha salido, aqui creamos el Thread run() y lo iniciamos, a su vez seteamos
     * el item del DropDown menu del ActionBar a la aplicacion actual.
     * @see http://developer.android.com/reference/android/app/Activity.html
     */
    @Override
    protected void onResume() {
        super.onResume();
        //Creo el Thread y lo inicio
        Running = true;
        myThread = new Thread(this);
        myThread.start();
    }

    /**
     * @author Andres
     * Cuando se pausa la Activity se elimina el Thread run() para liberar recursos ya que no sera usado y se lo iguala a null para
     * no provocar un error si por accidente se intenta usarlo
     */
    @Override
    protected void onPause() {
        super.onPause();
        //destruyo el Thread
        Running = false;
        try {
            myThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        myThread = null;    //pongo el Thread como null para no provocar errores
    }

    /**
     * @author Andres
     * Lee cada aproximadamente 500mS los datos que se tienen del analizador logico y los muestra en el grafico llamando a un Handler
     * debido a que el grafico debe ser actualizado desde el Main Thread.
     * @see "private Handler uiCallback = new Handler ()" debajo.
     */
    @Override
    public void run() {

        while(true){
            while(Running){

                if(DEBUG) Log.i(TAG, "run() -> LogicAnalizerView");
                uiCallback.sendEmptyMessage(0);
                if(DEBUG) Log.i(TAG, "run() -> LogicAnalizerView - Thread.sleep()");

                try { Thread.sleep(500); }
                catch (InterruptedException e) { e.printStackTrace(); }
            }

        try { Thread.sleep(500); }
        catch (InterruptedException e) { e.printStackTrace(); }

        }

    }

    /** 
     * @author Andres
     * Los Handlers ejecutan sus operaciones en el Thread de la UI haciendo posible la modificacion de la misma desde Threads no UI.
     * @see http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html
     * @see http://developer.android.com/reference/android/os/Handler.html
     */
    private Handler uiCallback = new Handler () {
        public void handleMessage (Message msg) {
            Running = false;
            if(DEBUG) Log.i(TAG, "XAxisMax: " + mRenderer.getXAxisMax() + " Time: " + time + " Ticks: " + Ticks);
            if(DEBUG) Log.i(TAG, "XAxisMin: " + mRenderer.getXAxisMin());
            final int[] factor = {0, 2, 4, 6};  // Valores tomados como 0 logicos

            // Si hay datos listos
            if(USBMulti.isLogicAnalizerDataRdy()){
                ReceptionBuffer = USBMulti.getLogicAnalizerData();      // Obtengo los datos desde el USB
            }

            // Si los bit son 1 le sumo 1 a los valores tomados como 0 logicos
            for(int n=0; n < ReceptionBuffer.length; ++n){              // Voy a traves de los bytes recibidos
                for(int bit=0; bit < 4; ++bit){     // Voy a traves de los 4 bits de cada byte
                    if(bitTest(ReceptionBuffer[n],bit)){
                        input[bit].add(time, factor[bit]+1);    
                    }
                    else{
                        input[bit].add(time, factor[bit]);
                    }
                }
                time += TimeIncrement;              // Incremento el tiempo
                ++Ticks;                            // Incremento ticks
                //Si llego al maximo del cuadro (borde derecho) aumento el maximo y el minimo para dibujar un tiempo mas
                //(desplazamiento del cuadro) de esta manera si deslizamos el cuadro horizontalmente tendremos los datos
                if(Ticks >= maxTicks){
                    mRenderer.setXAxisMax(mRenderer.getXAxisMax()+TimeIncrement);
                    mRenderer.setXAxisMin(mRenderer.getXAxisMin()+TimeIncrement);
                }
            }

            if(DEBUG) Log.i(TAG, "uiCallback -> LogicAnalizerView - mChartView.repaint()");
            if(mChartView != null) mChartView.repaint();    // Redibujo el grafico
            Running = true;
        }
    };
4

2 に答える 2

8

私はかなり単純な方法を使用しているので、基本的には私のプロジェクトの 1 つからのコピー/貼り付けです。うまくいけば、それを使用できます。明らかに、いくつかの部分を独自のもの、つまり設定、文字列、名前空間などに置き換える必要があります:-)

設定画面を表示:

startActivity(new Intent(getApplicationContext(), Preferences.class));

設定クラス:

import java.util.List;

import android.os.Bundle;
import android.preference.PreferenceActivity;

public class Preferences extends PreferenceActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public void onBuildHeaders(List<Header> target) {       
        loadHeadersFromResource(R.xml.preference_headers, target);
    }

}

Prefs クラス:

import android.os.Bundle;
import android.preference.PreferenceFragment;

public class Prefs extends PreferenceFragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        int res=getActivity().getResources().getIdentifier(getArguments().getString("resource"), "xml", getActivity().getPackageName());
        addPreferencesFromResource(res);
    }

}

preference_headers.xml (res/xml 内):

設定画面 (フラグメント) ごとにヘッダー リストが必要です。

<preference-headers xmlns:android="http://schemas.android.com/apk/res/android" >

    <header
        android:fragment="com.miz.mizuu.Prefs"
        android:icon="@drawable/search"
        android:title="@string/prefsIdentificationAndSearch" >
        <extra
            android:name="resource"
            android:value="preferences" />
    </header>
    <header
        android:fragment="com.miz.mizuu.Prefs"
        android:icon="@drawable/apptheme"
        android:title="@string/prefsUI" >
        <extra
            android:name="resource"
            android:value="preferences2" />
    </header>

</preference-headers>

Preferences.xml、preference2.xml など (/res/xml 内):

preference_headers.xml で参照される「エクストラ」ごとに個別の設定 xml ファイルが必要になります。これは、上記のコードがpreferences.xmlとpreferences2.xmlに依存していることを意味します。

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >

    <PreferenceCategory android:title="@string/prefsIdentification" >
        <CheckBoxPreference
            android:defaultValue="false"
            android:icon="@drawable/localizedinfo"
            android:key="prefsUseLocalData"
            android:summary="@string/prefsUseLocalDataDescription"
            android:title="@string/prefsUseLocalDataTitle" >
        </CheckBoxPreference>
    </PreferenceCategory>

</PreferenceScreen>
于 2012-05-01T23:41:32.143 に答える
0

からフラグメントをロードすることはできませんIntent。FragmentTransactionの使用など、既存のアクティビティにフラグメントを追加する必要があります。

実際にフラグメントにしたいようには思えないので、aに変更してから、PreferenceActivityインテントとstartActivityを使用してロードすることをお勧めします。

于 2012-05-01T23:34:42.853 に答える