0

Android デベロッパーの皆様、こんにちは。

アクティビティの再起動後、一部のビューの奇妙な動作に直面しています。「表示」されていないビューがいくつかありますが、それらはレイアウトされ、タッチ アクションに反応します。

アプリケーションを Android ライフタイム ガイドに準拠させようとしています。アクティビティをバックグラウンドにドロップし、システムにアクティビティを閉じさせます。次に、再作成されたアクティビティに戻ります。データが破損する (変更が行われるたびに db に保存される) ことに問題はありませんが、ビューは破損します。適切に表示されているものもありますが、ScrollView内にあるTableView内のすべてが表示されません。表示されていないビューのいずれかでgetVisibility()を呼び出すと、表示されていることがわかります。上で述べたように、ビューは「表示」されませんが、適切に表示されたように、タッチおよびスクロール イベントに反応します。

これもデバッグが困難 (不可能) です。これは、アプリが閉じられるとデバッガーが切断されるためです。しかし、とにかく、再生成はonCreate()onStart()onResume()という同じメソッド コールバックに従います。私にとっての唯一の違いは、アクティビティが新しく作成されたときにonCreate(Bundle)にnull Bundleがあり、システムによって再作成されたときにnullではないことです。アクティビティが (バックグラウンドで) 停止されただけで、システムによって閉じられていない場合、すべて正常に動作します。

onSaveInstanceState()onRestoreInstanceState( )をオーバーライドして、何も保存および復元しないようにしました (スーパー実装への呼び出しはありません) が、効果はありませんでした。

Android 4.1.1 とエミュレータ 2.1 を使用しています。

誰にもアイデアはありますか?

ありがとうエール

これをよりよく理解するためのスクリーンショット (へのリンク) を次に示します。
アクティビティがシステムによって閉じられる前 アクティビティ
が再作成された後

レイアウト ファイルは次のとおりです。

    <!-- Header --> 
    <LinearLayout
        android:id="@+id/startlistHeaderLayout" xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="horizontal" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content"
        >
        <TextView android:id="@+id/textStartlistName"
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content"
            android:lines="1"
            android:gravity="left"
            android:text=""
            />
        <TextView android:id="@+id/textStarttime"
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content"
            android:lines="1"
            android:gravity="right"
            android:text=""
            android:layout_weight="1"
            />
    </LinearLayout>

    <!-- Results --> 
    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@id/resultsScrollView"
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent"
        android:fillViewport="true"
        android:saveEnabled="false"
        >
        <TableLayout
            android:id="@id/timingLapTableLayout"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:stretchColumns="2"
            android:shrinkColumns="2"
            android:saveEnabled="false"
            >
            <!-- rows are added in code -->
        </TableLayout>
    </ScrollView>
</LinearLayout>

<!-- R.layout.timing_row -->
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@id/timingTableRow"
    android:saveEnabled="false"
    >
    <TextView
        android:id="@id/textTimingPosition"
        android:text=""
        android:gravity="right"
        android:paddingLeft="4dip"
        android:saveEnabled="false"
        />
    <TextView
        android:id="@id/textTimingBib"
        android:text=""
        android:gravity="right"
        android:paddingLeft="1dip"
        android:saveEnabled="false"
        />
    <TextView
        android:id="@id/textTimingName"
        android:text=""
        android:lines="1"
        android:ellipsize="end"
        android:gravity="left"
        android:paddingLeft="1dip"
        android:paddingRight="5dip"
        android:saveEnabled="false"
        />
    <TextView
        android:id="@id/textTimingBehind1"
        android:text=""
        android:gravity="right"
        android:paddingRight="5dip"
        android:saveEnabled="false"
        />
    <TextView
        android:id="@id/textTimingBehind2"
        android:text=""
        android:gravity="right"
        android:paddingRight="5dip"
        android:saveEnabled="false"
        />
</TableRow>

アクティビティ コードの一部を次に示します。

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(null);
    loadPreferencesTimingTheme();
    if (ownTheme) {
        this.setTheme(theme);
    } else {
        this.setTheme(MainActivity.theme);
    }
}

protected void onStart() {
    super.onStart();
    View lapView;
    View v;
    int sid;
    setContentView(R.layout.startlist_edit);
    sid = getIntent().getIntExtra(TimingActivity.STARTLIST_ID, -1);
    if (sid == -1) {
        Toast.makeText(this, "Sorry, could not load startlist.", Toast.LENGTH_LONG);
        this.finish();
        return;
    }
    tdb = new TimingDB(this);
    sl = tdb.getStartlist(sid); // get Startlist from db into memory
    // hide unnecessary columns
    v = findViewById(R.id.timingLapTableLayout);
    ((TableLayout) v).setColumnCollapsed(0, true);
    loadStartlist(sl); // inflate rows with startlist data and set listeners
    // load the preferences and set preferences listener
    loadPreferences();
    PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(prefsChangeListener);
}

public void onStop() {
    super.onStop();
    PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(prefsChangeListener);
    if (tdb != null) tdb.close();
}

protected void onSaveInstanceState (Bundle outState) {
    // super.onSaveInstanceState(outState);
}

protected void onRestoreInstanceState (Bundle savedInstanceState) {
    // super.onRestoreInstanceState(savedInstanceState);
}

protected void onDestroy() {
    super.onDestroy();
    if (tdb != null) tdb.close();
}

private void loadStartlist(StartList sl) {
    // set startlist name & time
    View v = findViewById(R.id.textStarttime);
    ((TextView) v).setText(SimpleDateFormats.ddmmyyyyhhmmss.format(new Date(sl.getStartTime())));
    v = findViewById(R.id.textStartlistName);
    ((TextView) v).setText(sl.getName());
    // set header onclicklistener
    v = findViewById(R.id.startlistHeaderLayout);
    v.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            // show dialog to change startlist name and time
            Bundle args = new Bundle();
            args.putString(KEY_NAME, ((TextView) findViewById(R.id.textStartlistName)).getText().toString());
            args.putString(KEY_STTIME, ((TextView) v.findViewById(R.id.textStarttime)).getText().toString());
            if (Build.VERSION.SDK_INT < 8) {
                dialogBundle = args;
                showDialog(DIALOG_EDIT_STARTLIST);
            } else {
                showDialog(DIALOG_EDIT_STARTLIST, args);
            }
        }
    });
    // add competitors to startlist
    int cnt = sl.getCompetitorsCount();
    for (int i = 0; i < cnt; i++) {
        Competitor c = sl.getCompetitorByIndex(i);
        appendStartlistRow(c);
    }
}

public void appendStartlistRow(final Competitor c) {
    TableRow inflatedView = (TableRow) getLayoutInflater().inflate(R.layout.timing_row, null);
    inflatedView.setTag(TAG_COMPETITOR, c);
    inflatedView.setTag(new Integer(c.getBib()));
    inflatedView.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            TableLayout tl = (TableLayout) findViewById(R.id.timingLapTableLayout);
            Bundle args = new Bundle();
            args.putInt(KEY_INDEX, tl.indexOfChild(v));
            if (Build.VERSION.SDK_INT < 8) {
                dialogBundle = args;
                showDialog(DIALOG_EDIT_COMPETITOR);
            } else {
                showDialog(DIALOG_EDIT_COMPETITOR, args);
            }
        }
    });
    // set up texts
    TextView text = (TextView) inflatedView.findViewById(R.id.textTimingBib);
    text.setText(c.getBib() + "");
    text = (TextView) inflatedView.findViewById(R.id.textTimingName);
    text.setText(c.getName());
    text = (TextView) inflatedView.findViewById(R.id.textTimingBehind1);
    text.setText(getFormatedStartTime(sl, c, Settings.STARTTIME_ABSOLUTE));
    text = (TextView) inflatedView.findViewById(R.id.textTimingBehind2);
    text.setText(getFormatedStartTime(sl, c, Settings.STARTTIME_RELATIVE));
    // append the row
    appendStartlistRow((ViewGroup) inflatedView);
}

public void appendStartlistRow(ViewGroup row) {
    // set background and text colors
    if (((((Integer) row.getTag()).intValue()) % 2) == Defs.VIEW_EVEN) {
        row.setBackgroundColor(Defs.COLOR_BACKGROUND_EVEN);
        for (int j = 0; j < row.getChildCount(); j++) {
            ((TextView) (row.getChildAt(j))).setTextColor(Defs.COLOR_TEXT_EVEN);
        }
    } else {
        row.setBackgroundColor(Defs.COLOR_BACKGROUND_ODD);
        for (int j = 0; j < row.getChildCount(); j++) {
            ((TextView) (row.getChildAt(j))).setTextColor(Defs.COLOR_TEXT_ODD);
        }
    }
    ((TableLayout) findViewById(R.id.timingLapTableLayout)).addView(row);
}

Defs.java:

public class Defs {
    protected static final int VIEW_EVEN = 0;
    protected static final int VIEW_ODD = 1;
    protected static int COLOR_BACKGROUND_EVEN;
    protected static int COLOR_BACKGROUND_ODD;
    protected static int COLOR_BACKGROUND_SELECTED;
    protected static int COLOR_BACKGROUND_SPYED;
    protected static int COLOR_TEXT_ODD;
    protected static int COLOR_TEXT_EVEN;
    protected static int COLOR_TEXT_SELECTED;
    protected static int COLOR_TEXT_SPYED;

    private static boolean isInitialized = false;

    protected static void init(Context c) {
        if (isInitialized) return;
        COLOR_BACKGROUND_EVEN = c.getResources().getColor(R.color.background_darker);
        COLOR_BACKGROUND_ODD = c.getResources().getColor(R.color.background_lighter);
        COLOR_BACKGROUND_SELECTED = c.getResources().getColor(R.color.background_selected);
        COLOR_BACKGROUND_SPYED = c.getResources().getColor(R.color.background_spyed);
        COLOR_TEXT_ODD = c.getResources().getColor(R.color.text_lighter);
        COLOR_TEXT_EVEN = c.getResources().getColor(R.color.text_darker);
        COLOR_TEXT_SELECTED = c.getResources().getColor(R.color.text_selected);
        COLOR_TEXT_SPYED = c.getResources().getColor(R.color.text_spyed);
        isInitialized = true;
    }
}
4

1 に答える 1

0

コードがなければ、問題自体について多くを語ることはほぼ不可能です。しかし、私は言いたいと思いました(コメントとしてはより適切ですが、まだできません)長いリスト(あなたのリストはスクリーンショットに基づいているようです)の場合、実際ListViewのカスタムを使用ArrayAdapterする方が良い解決策かもしれません. ListViewスクロール時にビューを再利用するため、不要なビューの作成が減ります。また、 の使用方法を習得すれば、ListView表の行を手動で追加するよりも簡単であることがわかるでしょう。それらに慣れていない場合は、こちらのチュートリアルを確認してください: http://www.vogella.com/articles/AndroidListView/article.html

また、テーブルから に変更することにした場合ListView、問題 (それが何であれ) も同様に消える可能性があります。あなたは、決して知らない。:)

于 2013-10-28T19:01:40.707 に答える