9

アプリケーションに、ImageView と 3 ~ 5 個の TextView を含むカスタム ListView があります。

TextViews の 1 は、現在の時刻とその ListView アイテムに指定された時刻との間の時間差を示します。

いいね: 5 分前に投稿

問題は、ListView を乱すことなく、この TextView を毎分更新するにはどうすればよいかということです。

のように: ListView を 5 分間見ている場合、この TextView だけを 1 分から 2 分に変更する必要があります。

私が試したこと:

  1. を使用してgetView()でこの TextView を設定しますSystem.currentTimeMillis() - givenTime[position];

しかし、ここでは、スクロールしていない (getView を呼び出していない) か、アイテムの可視性を変更していない場合、TextView は更新されません。

  1. timeTask()スレッドを 1 分ごとに使用し、すべてのアイテムの TextView を更新してみてください

ここで問題は、例外が発生することです:

android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

さらに、アクティビティからすべての ListView アイテムの TextView を変更する方法がわかりません。

しかし、これはおなじみのケースのようです。

どうすればこれを達成できますか?

ありがとうございました

4

4 に答える 4

38

aHandlerとそのpostDelayedメソッドを使用して、次のようにリストのアダプターを無効にします。

final Handler handler = new Handler()
handler.postDelayed( new Runnable() {

    @Override
    public void run() {
        adapter.notifyDataSetChanged();
        handler.postDelayed( this, 60 * 1000 );
    }
}, 60 * 1000 );

メイン (UI) スレッドでのみ UI を更新する必要があります。

メイン スレッドでハンドラーを作成することにより、ハンドラーにポストするすべてのものがメイン スレッドでも実行されるようにします。

于 2012-10-16T13:50:23.060 に答える
4

TextView毎秒、毎分、または毎時更新するカスタムを作成することもできます。TextViewこれは、そのクラス内に Handlerを拡張して追加するクラスを作成することで簡単に実行できます。利点は、ListView 全体を更新する必要がないことです。TextView は自動的に更新されます。

例:

public class TextViewTimeCounter extends TextView {
private long mStartTime = 0;
private long mTimeNow = 0;
private int mDelay = 0;
private String mPart1 = "";
private String mPart2 = "";

private Handler mHandler;

public TextViewTimeCounter(Context context) {
    super(context, null, 0);
}

public TextViewTimeCounter(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public TextViewTimeCounter(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

public void startTimer(long delay, String part1, String part2){
    mStartTime = System.currentTimeMillis();
    mTimeNow = System.currentTimeMillis();
    mDelay = delay;
    mHandler = new Handler();
    mHandler.postDelayed(r, delay);
    convertDatesToMinutes(mStartTime, mTimeNow);
}

public void stopTimer(){
    if(mHandler != null){
        mHandler = null;
        mStartTime = 0;
        mTimeNow = 0;
    }
}

public boolean isTimerRunning(){
    return mHandler == null? false : true;
}


Runnable r = new Runnable() {
    @Override
    public void run(){
        mTimeNow += mDelay;
        convertDatesToMinutes(mStartTime, mTimeNow);
        if(mHandler != null){
            mHandler.postDelayed(r, mDelay);
        }
    }
};



public void convertDatesToMinutes(long start, long end){
    long secs = (end - start);
    long minute = (secs / (1000 * 60)) % 60;
    long hour = (secs / (1000 * 60 * 60)) % 24;
    String time = String.format(Locale.getDefault(), "%2d hours %2d minutes", hour, minute);

    setText(mPart1 + time + mPart2);
}

使用法:

TextViewTimeCounter timer = (TextViewTimeCounter)convertView.findViewById(R.id.start_logging_time_text);
timer.startTimer(10000, "Posted ", " ago");

出力は次のようになります。

 Posted 1 hours 5 minutes ago

秒も表示する場合は、convertDatesToMinutes(long start, long end)メソッドを次のように変更します。

public void convertDatesToMinutes(long start, long end){
        long secs = (end - start);
        long second = (secs / 1000) % 60;
        long minute = (secs / (1000 * 60)) % 60;
        long hour = (secs / (1000 * 60 * 60)) % 24;
        String time = String.format(Locale.getDefault(), "%2d hours %2d minutes %2d seconds", hour, minute, second);
        setText(mPart1 + time + mPart2);
}
于 2014-08-30T12:24:09.320 に答える
3

組み込みの TimerTask を使用する

http://developer.android.com/reference/java/util/TimerTask.html

これは物事を行うための堅実な方法です。

于 2014-07-07T14:47:54.097 に答える