среда, 27 марта 2013 г.

Самопечатающий TextView

Самопечатающий TextView
Сегодня мы разработаем элемент, который будет посимвольно печатать заданный текст на экран.




Разработка TypewriterTextView


В основе нашего класса будет обычный TextView. Создадим новый класс TypewriterTextView и унаследуем его от TextView.
public class TypewriterTextView extends TextView {
 
   
    public TypewriterTextView(Context context) {
        super(context);
    }
    
    public TypewriterTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    public TypewriterTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
}

Добавим нашему классу следующие атрибуты:
- Время отображения одного символа
private final static float TEXT_CHARACTER_DELAY = 0.1f;
private final static int TEXT_CHARACTER_DELAY_MS = (int)(TEXT_CHARACTER_DELAY * 1000);
- индекс текущего символа  
private int mCurrentCharacter;
- время, прошедшее с момента отображения последнего символа
private long mLastTime;
- отображаемый текст
private CharSequence mText;
Переопределим метод отрисовки onDraw для отображения текста посимвольно.
public void onDraw(Canvas canvas) {
        final long time = SystemClock.uptimeMillis();
        final long delta = time - mLastTime;
        if (delta > TEXT_CHARACTER_DELAY_MS) {
            if (mText != null) {
                if (mCurrentCharacter <= mText.length()) {
                    CharSequence subtext = mText.subSequence(0, mCurrentCharacter);
                    setText(subtext, TextView.BufferType.SPANNABLE);
                    mCurrentCharacter++;
                    postInvalidateDelayed(TEXT_CHARACTER_DELAY_MS);
                }
            }
        }
        super.onDraw(canvas);
    }

Добавим метод для задания нового текста
public void setTypewriterText(CharSequence text) {
        mText = text;
        mCurrentCharacter = 0;
        mLastTime = 0;
        postInvalidate();
    }

И метод для отображения всего текста целиком
public void snapToEnd() {
        mCurrentCharacter = mText.length() - 1; 
    }

Подготовка ресурсов

Исходный код строковых ресурсов (values/strings)
   <resources>
      <string name="app_name">TypewriterTextView</string>
      <string name="btn_txt">Напечатать</string>
      <string name="sample_text">Android powers hundreds of millions of mobile devices in more than 190 countries around the world. It\'s the largest installed base of any mobile platform and growing fast—every day another million users power up their Android devices for the first time and start looking for apps, games, and other digital content.</string>
   </resources>
Макет приложения будет состоять из поля для ввода текста, кнопки и самопечатающего TextView.
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <EditText
        android:id="@+id/typeEd"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/typeBtn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn_txt" />

    <org.snowpard.proects.seventeen.TypewriterTextView
        android:id="@+id/typeTxt"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

   </LinearLayout>

MainActivity

Исходный код основной Activity
public class MainActivity extends Activity {
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  
  final TypewriterTextView ttv = (TypewriterTextView)findViewById(R.id.typeTxt);
  ttv.setTypewriterText(getString(R.string.sample_text));
  ttv.setOnClickListener(new OnClickListener() {
   
   @Override
   public void onClick(View v) {
    ttv.snapToEnd();
   }
  });
  
  final EditText et = (EditText)findViewById(R.id.typeEd);
  Button btn = (Button)findViewById(R.id.typeBtn);

  btn.setOnClickListener(new OnClickListener() {
   
   @Override
   public void onClick(View v) {
    ttv.setTypewriterText(et.getText());
   }
  });
 }


}

Ссылки


  • Исходные коды данного проекта можно скачать отсюда: zip