Updating TextView with clock

假装没事ソ 提交于 2019-12-06 15:53:51

问题


I have been trying to create a program that will output a working digital clock that will allow me to quickly access the date and time. I have the code to parse the time, however, I'm having difficulty updating the textview. I have this:

    `public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    timer = (TextView)findViewById(R.id.timer);

    time = new Time();
    time.setToNow();

    timeString = time.toString();
    changeTime = Parser(timeString);


    time.setToNow();
    timeString = time.toString();
    changeTime = Parser(timeString);

    timer.setText(changeTime);  
    } 
    private String Parser(String time){

    String year = time.substring(0, 4);
    String month = time.substring(4,6);
    String day = time.substring(6, 8);
    String hour = time.substring(9,11);
    String minute = time.substring(11, 13);
    String second = time.substring(13, 15);

    String finalTime = hour + ":" + minute + ":" + second + " " + day + " " + month + " "  + year;
    //String finalTime = second;
    return finalTime;


}`

How do I put this in a loop to constantly update the textview.

Thanks for any help you can give me.


回答1:


Declare a Handler to update the TextView on the UI thread.

private Handler mHandler = new Handler() {
 @Override
 public void handleMessage(Message msg) {
    time = new Time();
    time.setToNow();

    timeString = time.toString();
    changeTime = Parser(timeString); 
    timer.setText(changeTime);  
 }
};

Start a TimeTask that will update your TextView

int initialDelay = 1000; //first update in miliseconds
int period = 5000;      //nexts updates in miliseconds       

Timer timer = new Timer();
TimerTask task = new TimerTask() {
  public void run() {
      Message msg = new Message();
      mHandler.sendMessage(msg);
  }
};
timer.scheduleAtFixedRate(task, initialDelay, period);



回答2:


You should use a timer thread. You can also simplify your time and date conversions by using Calendar, and can optimize your String creation by using format. This example will update your TextView every second (1000ms):

Timer t = new Timer();
timer = (TextView)findViewById(R.id.timer);

t.scheduleAtFixedRate(new TimerTask() 
{
    @Override
    public void run() {
        Calendar c = Calendar.getInstance();
        final String finalTime = String.format(Locale.US, "%d:%d:%d %d/%d/%d", c.get(Calendar.HOUR), c.get(Calendar.MINUTE), c.get(Calendar.SECOND), c.get(Calendar.DAY_OF_MONTH), c.get(Calendar.MONTH), c.get(Calendar.YEAR));

        runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    timer.setText(finalTime);
                }
            });
    }

}, 1000, 1000); //Initial Delay and Period for update (in milliseconds)



回答3:


This can be done easily with the help of a thread in android but as you want to access the ui so threads won't work help you. you should better choose handlers or timertask

However async tasks also run on Non-ui thread so make an handler inside a timertask..

Timer t=Timer();

    t.scheduleAtFixedRate(new TimerTask(new Runnable()
        {
    public void run(){
    Handler h=new Handler(getMainLooper());
    h.post(new Runnable(
){public void run(){
//get the time here and set the textview here as here it has access to the main ui
}});
    }
    }
    ), long delay, Long period);

Sorry for bad code formatting ...but it will work for you




回答4:


It is a bad practice to start updating the view with never ending handler messages (try it an look at the CPU level of your process). The better and more elegant way is to register a BroadcastReceiver which will trigger the update.

public class Clock extends LinearLayout {

    private Calendar mCalendar;
    private LinearLayout mLayoutTime;
    private TextView mAMPMText;
    private TextView mDateText;
    private TextView mTimeText;
    private View mSendFeedback;
    private boolean mAttached;

    private final Handler mHandler = new Handler();
    SimpleDateFormat dateFormatter = new SimpleDateFormat("EEE, MMM d, yyyy");
    SimpleDateFormat timeFormatter = new SimpleDateFormat("h:mm");

    public Clock(final Context context, int layoutResourceID, int dateResId, int meResId,int amPmResId) {
        super(context);
        LayoutInflater layoutInflater = LayoutInflater.from(context);
        View view = layoutInflater.inflate(layoutResourceID, null);
        addView(view, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        mAMPMText = (TextView) view.findViewById(amPmResId);
        mTimeText = (TextView) view.findViewById(timeResId);
        mDateText = (TextView) view.findViewById(dateResId);    
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();

        if (!mAttached) {
            mAttached = true;
            IntentFilter filter = new IntentFilter();

            filter.addAction(Intent.ACTION_TIME_TICK);
            filter.addAction(Intent.ACTION_TIME_CHANGED);
            filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);

            getContext().registerReceiver(mIntentReceiver, filter, null, mHandler);
        }

        // NOTE: It's safe to do these after registering the receiver since the receiver always runs
        // in the main thread, therefore the receiver can't run before this method returns.

        // The time zone may have changed while the receiver wasn't registered, so update the Time
        mCalendar = Calendar.getInstance();

        // Make sure we update to the current time
        onTimeChanged();
        updateView();
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (mAttached) {
            getContext().unregisterReceiver(mIntentReceiver);
            mAttached = false;
        }
    }

    private void updateView(){
        mTimeText.setText(timeFormatter.format(mCalendar.getTime()));
        mDateText.setText(dateFormatter.format(mCalendar.getTime()));
        mAMPMText.setText(mCalendar.get(Calendar.AM_PM) == 0 ? "AM" : "PM");
    }

    private void onTimeChanged() {
        mCalendar.setTime(new Date());

        updateContentDescription(mCalendar);
    }

    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)) {
                String tz = intent.getStringExtra("time-zone");
                mCalendar.setTimeZone(TimeZone.getTimeZone(tz));
            }

            onTimeChanged();

            updateView();
        }
    };

    private void updateContentDescription(Calendar calendar) {
        setContentDescription(calendar.toString());
    }
}

The layout (can be done better)

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:gravity="center_vertical"
    android:orientation="horizontal" >

    <LinearLayout
        android:id="@+id/layout_time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/time_txt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:includeFontPadding="true" />

        <TextView
            android:id="@+id/am_pm_txt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="AM" />
    </LinearLayout>

    <TextView
        android:id="@+id/date_txt"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</RelativeLayout>


来源:https://stackoverflow.com/questions/16153971/updating-textview-with-clock

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!