SimpleCursorAdapter.getItemId () для подробного фрагмента. Как передать _id?

1

Я пишу FragmentActivity где у меня есть ListFragment (с использованием SimpleCursorAdapter), detailFragment и detailActivity (который используется, когда телефон находится на портрете, вставляйте detailsFragment).
Когда я нажимаю на один элемент в списке, он должен заполнить detailFragment данными из второго курсора, построенного с использованием _id выбранного элемента в качестве selectionArgs.
Но, то _id, кажется, не проходит, я получил тост в ListFragment, где я показываю _id выбранного элемента (и это правильно), но в detailsFragment _id никогда не приходит (он остается равен 0, посылая NullPointerException). Где я ошибаюсь?

EDIT: Я забыл сказать также, что когда я возвращаюсь из detailsActivity с помощью кнопки "Назад", список пуст, и он говорит что-то о закрытии базы данных.
Сообщения Logcat можно найти в конце моего сообщения.

Родительская активность

package com.gmail.david.corsalini.sportscout;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;

public class MatchesRugbyPage extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.matches_rugby);
    }
}

MatchesListFragment (мой ListFragment)

package com.gmail.david.corsalini.sportscout;

import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.ListFragment;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;

/**
 * This is the "top-level" fragment, showing a list of items that the user can
 * pick. Upon picking an item, it takes care of displaying the data to the user
 * as appropriate based on the current UI layout.
 */
public class MatchesListFragment extends ListFragment {
    boolean mDualPane;
    private Cursor cursor;
    private SimpleCursorAdapter myAdapter;
    private long MATCH_ID;
    private int selected;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        // Database
        DBSportScout db = new DBSportScout(getActivity());
        db.open();
        // Cursor
        String[] selection = { DBSportScout.MatchMetaData.KEY_MNAME,
                DBSportScout.MatchMetaData.KEY_MROWID };
        cursor = db.fetch(DBSportScout.MatchMetaData.DATABASE_TABLE_MATCH,
                selection, null, null, null, null, null, null);
        getActivity().startManagingCursor(cursor);
        // Adapter
        String[] columns = { DBSportScout.MatchMetaData.KEY_MNAME };
        int[] to = { R.id.tv1ListItem };
        myAdapter = new SimpleCursorAdapter(getActivity(),
                R.layout.ss_list_item, cursor, columns, to);
        setListAdapter(myAdapter);
        db.close();

        // Check to see if we have a frame in which to embed the details
        // fragment directly in the containing UI.
        View detailsFrame = getActivity().findViewById(R.id.detailsFrame);
        mDualPane = detailsFrame != null
                && detailsFrame.getVisibility() == View.VISIBLE;

        if (savedInstanceState != null) {
            // Restore last state for checked position.
            MATCH_ID = savedInstanceState.getLong("curChoice", 0);
        }

        if (mDualPane) {
            // In dual-pane mode, the list view highlights the selected item.
            getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
            // Make sure our UI is in the correct state.
            showDetails(MATCH_ID);
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putLong("curChoice", MATCH_ID);
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        selected = position;
        MATCH_ID = myAdapter.getItemId(position);
        Toast.makeText(getActivity(), "Partita n. " + Long.toString(MATCH_ID),
                Toast.LENGTH_SHORT).show();
        showDetails(MATCH_ID);
        Log.i("Partita", "ID Partita selezionata= " + MATCH_ID);
    }

    /**
     * Helper function to show the details of a selected item, either by
     * displaying a fragment in-place in the current UI, or starting a whole new
     * activity in which it is displayed.
     */

    public void showDetails(long matchid) {

        if (mDualPane) {
            // We can display everything in-place with fragments, so update
            // the list to highlight the selected item and show the data.
            getListView().setItemChecked(selected, true);

            // Check what fragment is currently shown, replace if needed.
            MatchDetailsFragment f = (MatchDetailsFragment) getFragmentManager()
                    .findFragmentById(R.id.detailsFrame);
            if (f == null || f.getMATCH_ID() != matchid) {
                // Make new fragment to show this selection.
                f = new MatchDetailsFragment();

                // Supply index input as an argument.
                Bundle args = new Bundle();
                args.putLong("matchid", matchid);
                f.setArguments(args);

                // Execute a transaction, replacing any existing fragment
                // with this one inside the frame.
                FragmentTransaction ft = getFragmentManager()
                        .beginTransaction();
                ft.replace(R.id.detailsFrame, f);
                ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
                ft.addToBackStack(null);
                ft.commit();
            }

        } else {
            // Otherwise we need to launch a new activity to display
            // the dialog fragment with selected text.
            Intent intent = new Intent();
            intent.setClass(getActivity(), MatchDetailsActivity.class);
            intent.putExtra("index", matchid);
            startActivity(intent);
        }
    }

}

MatchDetailFragment (мои подробностиFragment)

package com.gmail.david.corsalini.sportscout;

import com.gmail.david.corsalini.sportscout.DBSportScout.MatchMetaData;

import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

/**
 * This is the secondary fragment, displaying the details of a particular item.
 */
public class MatchDetailsFragment extends Fragment {

    /**
     * Create a new instance of DetailsFragment, initialized to show the text at
     * 'matchid'.
     */
    public static MatchDetailsFragment newInstance(long matchid) {
        MatchDetailsFragment f = new MatchDetailsFragment();

        // Supply index input as an argument.
        Bundle args = new Bundle();
        args.putLong("matchid", matchid);
        f.setArguments(args);
        return f;
    }

    private TextView tvfTriesA;
    private TextView tvfTriesB;
    private TextView tvfName;
    private long MATCH_ID;
    public long getMATCH_ID() {
        MATCH_ID = getArguments().getLong("matchid", 0);
        return MATCH_ID;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        if (container == null) {
            // We have different layouts, and in one of them this
            // fragment containing frame doesn't exist. The fragment
            // may still be created from its saved state, but there is
            // no reason to try to create its view hierarchy because it
            // won't be displayed. Note this is not needed -- we could
            // just run the code below, where we would create and return
            // the view hierarchy; it would just never be used.
            return null;
        }
        View view = inflater.inflate(R.layout.match_summary, container, false);
        populateDetails(MATCH_ID);
        return view;
    }

    public void populateDetails(long matchid) {

        // Create textviews
        tvfName = (TextView) getActivity().findViewById(R.id.tvfName);
        tvfTriesA = (TextView) getActivity().findViewById(R.id.tvfTriesA);
        tvfTriesB = (TextView) getActivity().findViewById(R.id.tvfTriesB);
        tvfName.setText(Long.toString(MATCH_ID));

        // Populate textviews
        DBSportScout db = new DBSportScout(getActivity());
        db.open();
        String selectionmatchid = Long.toString(matchid);
        String[] columns = { DBSportScout.MatchMetaData.KEY_MNAME,
                DBSportScout.MatchMetaData.KEY_MDATE,
                DBSportScout.MatchMetaData.KEY_MSTATUS,
                DBSportScout.MatchMetaData.KEY_MSUMMARY,
                DBSportScout.MatchMetaData.KEY_MTEAM_A_ID,
                DBSportScout.MatchMetaData.KEY_MTEAM_B_ID,
                DBSportScout.MatchMetaData.KEY_MCHAMP_ID,
                DBSportScout.MatchMetaData.KEY_MTURN,
                DBSportScout.MatchMetaData.KEY_MSPORT_ID,
                DBSportScout.MatchMetaData.KEY_MSCORE_A,
                DBSportScout.MatchMetaData.KEY_MSCORE_B,
                DBSportScout.MatchMetaData.KEY_MSTAT1_A,
                DBSportScout.MatchMetaData.KEY_MSTAT1_B,
                DBSportScout.MatchMetaData.KEY_MSTAT2_A,
                DBSportScout.MatchMetaData.KEY_MSTAT2_B,
                DBSportScout.MatchMetaData.KEY_MSTAT3_A,
                DBSportScout.MatchMetaData.KEY_MSTAT3_B,
                DBSportScout.MatchMetaData.KEY_MSTAT4_A,
                DBSportScout.MatchMetaData.KEY_MSTAT4_B,
                DBSportScout.MatchMetaData.KEY_MSTAT5_A,
                DBSportScout.MatchMetaData.KEY_MSTAT5_B,
                DBSportScout.MatchMetaData.KEY_MSTAT6_A,
                DBSportScout.MatchMetaData.KEY_MSTAT6_B,
                DBSportScout.MatchMetaData.KEY_MSTAT7_A,
                DBSportScout.MatchMetaData.KEY_MSTAT7_B,
                DBSportScout.MatchMetaData.KEY_MSTAT8_A,
                DBSportScout.MatchMetaData.KEY_MSTAT8_B,
                DBSportScout.MatchMetaData.KEY_MSTAT9_A,
                DBSportScout.MatchMetaData.KEY_MSTAT9_B,
                DBSportScout.MatchMetaData.KEY_MSTAT10_A,
                DBSportScout.MatchMetaData.KEY_MSTAT10_B,
                DBSportScout.MatchMetaData.KEY_MSTAT11_A,
                DBSportScout.MatchMetaData.KEY_MSTAT11_B,
                DBSportScout.MatchMetaData.KEY_MSTAT12_A,
                DBSportScout.MatchMetaData.KEY_MSTAT12_B,
                DBSportScout.MatchMetaData.KEY_MSTAT13_A,
                DBSportScout.MatchMetaData.KEY_MSTAT13_B,
                DBSportScout.MatchMetaData.KEY_MSTAT14_A,
                DBSportScout.MatchMetaData.KEY_MSTAT14_B,
                DBSportScout.MatchMetaData.KEY_MSTAT15_A,
                DBSportScout.MatchMetaData.KEY_MSTAT15_B,
                DBSportScout.MatchMetaData.KEY_MSTAT16_A,
                DBSportScout.MatchMetaData.KEY_MSTAT16_B,
                DBSportScout.MatchMetaData.KEY_MSTAT17_A,
                DBSportScout.MatchMetaData.KEY_MSTAT17_B,
                DBSportScout.MatchMetaData.KEY_MSTAT18_A,
                DBSportScout.MatchMetaData.KEY_MSTAT18_B,
                DBSportScout.MatchMetaData.KEY_MSTAT19_A,
                DBSportScout.MatchMetaData.KEY_MSTAT19_B,
                DBSportScout.MatchMetaData.KEY_MSTAT20_A,
                DBSportScout.MatchMetaData.KEY_MSTAT20_B,
                DBSportScout.MatchMetaData.KEY_MSTAT21_A,
                DBSportScout.MatchMetaData.KEY_MSTAT21_B,
                DBSportScout.MatchMetaData.KEY_MSTAT22_A,
                DBSportScout.MatchMetaData.KEY_MSTAT22_B,
                DBSportScout.MatchMetaData.KEY_MSTAT23_A,
                DBSportScout.MatchMetaData.KEY_MSTAT23_B,
                DBSportScout.MatchMetaData.KEY_MSTAT24_A,
                DBSportScout.MatchMetaData.KEY_MSTAT24_B,
                DBSportScout.MatchMetaData.KEY_MSTAT25_A,
                DBSportScout.MatchMetaData.KEY_MSTAT25_B,
                DBSportScout.MatchMetaData.KEY_MSTAT26_A,
                DBSportScout.MatchMetaData.KEY_MSTAT26_B,
                DBSportScout.MatchMetaData.KEY_MSTAT27_A,
                DBSportScout.MatchMetaData.KEY_MSTAT27_B,
                DBSportScout.MatchMetaData.KEY_MSTAT28_A,
                DBSportScout.MatchMetaData.KEY_MSTAT28_B,
                DBSportScout.MatchMetaData.KEY_MSTAT29_A,
                DBSportScout.MatchMetaData.KEY_MSTAT29_B,
                DBSportScout.MatchMetaData.KEY_MSTAT30_A,
                DBSportScout.MatchMetaData.KEY_MSTAT30_B,
                DBSportScout.MatchMetaData.KEY_MSTAT31_A,
                DBSportScout.MatchMetaData.KEY_MSTAT31_B,
                DBSportScout.MatchMetaData.KEY_MSTAT32_A,
                DBSportScout.MatchMetaData.KEY_MSTAT32_B,
                DBSportScout.MatchMetaData.KEY_MSTAT33_A,
                DBSportScout.MatchMetaData.KEY_MSTAT33_B,
                DBSportScout.MatchMetaData.KEY_MSTAT34_A,
                DBSportScout.MatchMetaData.KEY_MSTAT34_B,
                DBSportScout.MatchMetaData.KEY_MSTAT35_A,
                DBSportScout.MatchMetaData.KEY_MSTAT35_B,
                DBSportScout.MatchMetaData.KEY_MSTAT36_A,
                DBSportScout.MatchMetaData.KEY_MSTAT36_B,
                DBSportScout.MatchMetaData.KEY_MSTAT37_A,
                DBSportScout.MatchMetaData.KEY_MSTAT37_B,
                DBSportScout.MatchMetaData.KEY_MSTAT38_A,
                DBSportScout.MatchMetaData.KEY_MSTAT38_B,
                DBSportScout.MatchMetaData.KEY_MSTAT39_A,
                DBSportScout.MatchMetaData.KEY_MSTAT39_B,
                DBSportScout.MatchMetaData.KEY_MSTAT40_A,
                DBSportScout.MatchMetaData.KEY_MSTAT40_B };
        String[] selectionArgs = { selectionmatchid };

        Cursor c = db.fetch(DBSportScout.MatchMetaData.DATABASE_TABLE_MATCH,
                columns, DBSportScout.MatchMetaData.KEY_MROWID + "=?",
                selectionArgs, null, null, null, null);
        c.moveToFirst();

        tvfName.setText(c.getInt(c.getColumnIndexOrThrow(DBSportScout.MatchMetaData.KEY_MNAME)));
        tvfTriesA.setText(c.getInt(c.getColumnIndexOrThrow(DBSportScout.MatchMetaData.KEY_MSTAT1_A)));
        tvfTriesB.setText(c.getInt(c.getColumnIndexOrThrow(DBSportScout.MatchMetaData.KEY_MSTAT1_B)));
        db.close();
    }
}

Метод fetch() из DBSportScout

public Cursor fetch(String table, String[] columns, String selection,
        String[] args, String groupby, String having, String orderby,
        String limit) { // metodo per fare la query di tutti i dati
    Cursor cursor = mDb.query(table, columns, selection, args, groupby,
            having, orderby, limit);
    if (cursor != null) {
        cursor.moveToFirst();
    }
    return cursor;
}

Наконец, вот LogCat

FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.gmail.david.corsalini.sportscout/com.gmail.david.corsalini.sportscout.MatchesRugbyPage}: java.lang.NullPointerException
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
    at android.app.ActivityThread.access$600(ActivityThread.java:123)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4424)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
    at com.gmail.david.corsalini.sportscout.MatchDetailsFragment.populateDetails(MatchDetailsFragment.java:77)
    at com.gmail.david.corsalini.sportscout.MatchDetailsFragment.onCreateView(MatchDetailsFragment.java:64)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:870)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1080)
    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:622)
    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1416)
    at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:505)
    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1133)
    at android.app.Activity.performStart(Activity.java:4475)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1929)
    ... 11 more
Теги:
android-fragments
simplecursoradapter
android-listfragment

2 ответа

0
Лучший ответ

Я никогда не использовал пакет, если бы не начал новую деятельность. То, что я обычно делаю (и я не утверждаю, что это лучший способ, но он работает для меня), заключается в определении публичной статической переменной для хранения идентификатора строки, а затем ее использования.

Пример (только соответствующие биты).

Фрагмент 1 (Список пользователей):

public static Long mRowId;

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    mRowId = id;
    MemberDisplayFragment memberdisplay = new MemberDisplayFragment();
    getFragmentManager().beginTransaction().replace(R.id.rightpane, memberdisplay).commit();
}

Фрагмент 2 (Детальный просмотр участника):

Cursor memberdisplay = mDbHelper.fetchMember(MemberListFragment.mRowId);
getActivity().startManagingCursor(memberdisplay);
memberdisplay.moveToFirst();

Надеюсь это поможет!

  • 0
    Это кажется правильным, поэтому я изменил метод getMATCH_ID () в detailsFragment на MATCH_ID = MatchesListFragment.MATCH_ID; вернуть MATCH_ID; Затем я положил MATCH_ID = getMATCH_ID (); в populateDetails () (первая строка), но я получаю нулевое исключение в tvfName.setText (Long.toString (MATCH_ID)); что я не могу объяснить!
  • 0
    Попробуйте вместо этого: полностью потеряйте метод getMATCH_ID и просто обращайтесь к MATCH_ID из исходного фрагмента всякий раз, когда вам это нужно. Set tvfName.setText(Long.toString(MatchesListFragment.MATCH_ID)); и посмотрим, что получится.
Показать ещё 4 комментария
0

Когда вы делаете запрос, вы не запрашиваете столбец _ID в проекции

String[] selection= {DBSportScout.MatchMetaData.KEY_MNAME, DBSportScout.MatchMetaData.KEY_MROWID };

Поэтому он всегда будет равен нулю, я думаю, вам, возможно, нужно переопределить ваш адаптер, чтобы вернуть свой идентификатор выбора, или добавить столбец _id в таблицу.

  • 0
    KEY_MROWID = "_id" Это один из столбцов, когда я создаю таблицу. Фактически, тост, когда я щелкаю элемент в списке, возвращает мне правильный _id элемента, но он никогда не передается другому фрагменту.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню