2015-02-18 14 views
5

Tôi có một TextView với một số văn bản bên trong và tôi muốn nó hoạt ảnh động với hoạt ảnh di chuyển của vùng chọn. Tôi thấy điều này popular question về buộc hoạt hình marquee, tuy nhiên mã trong câu trả lời chỉ hoạt động nếu văn bản đủ dài để đi ra ngoài giới hạn của TextView (và do đó văn bản bị cắt ngắn), tôi đang tìm kiếm giải pháp để thực hiện vĩnh viễn văn bản có hoạt ảnh marquee này bất kể chiều rộng của văn bản; điều này có thể không?Android TextView: có cách nào để buộc hoạt ảnh của người dùng có văn bản ngắn không?

+0

Điểm của hoạt ảnh marquee là gì nếu văn bản không đủ dài để vượt quá giới hạn của TextView? – Karakuri

+0

Nó cho một số văn bản tiêu đề, và vì lợi ích của sự nhất quán/thương hiệu tôi muốn các hình ảnh động luôn luôn trên EDIT: và nó có vẻ tốt đẹp rõ ràng: P – AndroidNoob

Trả lời

3

Lấy @ đề nghị JodiMiddleton về đệm văn bản tôi xây dựng một vài phương pháp helper để pad chữ sang chiều rộng mục tiêu dựa trên đối tượng TextPaint (đảm bảo định kích thước chính xác từ phông chữ vv khi đo):

/** 
* Pad a target string of text with spaces on the right to fill a target 
* width 
* 
* @param text The target text 
* @param paint The TextPaint used to measure the target text and 
*   whitespaces 
* @param width The target width to fill 
* @return the original text with extra padding to fill the width 
*/ 
public static CharSequence padText(CharSequence text, TextPaint paint, int width) { 

    // First measure the width of the text itself 
    Rect textbounds = new Rect(); 
    paint.getTextBounds(text.toString(), 0, text.length(), textbounds); 

    /** 
    * check to see if it does indeed need padding to reach the target width 
    */ 
    if (textbounds.width() > width) { 
     return text; 
    } 

    /* 
    * Measure the text of the space character (there's a bug with the 
    * 'getTextBounds() method of Paint that trims the white space, thus 
    * making it impossible to measure the width of a space without 
    * surrounding it in arbitrary characters) 
    */ 
    String workaroundString = "a a"; 
    Rect spacebounds = new Rect(); 
    paint.getTextBounds(workaroundString, 0, workaroundString.length(), spacebounds); 

    Rect abounds = new Rect(); 
    paint.getTextBounds(new char[] { 
     'a' 
    }, 0, 1, abounds); 

    float spaceWidth = spacebounds.width() - (abounds.width() * 2); 

    /* 
    * measure the amount of spaces needed based on the target width to fill 
    * (using Math.ceil to ensure the maximum whole number of spaces) 
    */ 
    int amountOfSpacesNeeded = (int)Math.ceil((width - textbounds.width())/spaceWidth); 

    // pad with spaces til the width is less than the text width 
    return amountOfSpacesNeeded > 0 ? padRight(text.toString(), text.toString().length() 
      + amountOfSpacesNeeded) : text; 
} 

/** 
* Pads a string with white space on the right of the original string 
* 
* @param s The target string 
* @param n The new target length of the string 
* @return The target string padded with whitespace on the right to its new 
*   length 
*/ 
public static String padRight(String s, int n) { 
    return String.format("%1$-" + n + "s", s); 
} 

Vì vậy, khi bạn sử dụng các phương pháp dựa trên một TextView bạn sẽ gọi:

textView.setText(padText(myTargetString, textView.getPaint(), textView.getWidth())); 

Đó không phải là thanh lịch và tôi gần như chắc chắn có những cải tiến mà có thể được thực hiện (chưa kể đến một cách tốt hơn để làm việc đó) nhưng dù sao tôi đang sử dụng nó trong mã của tôi và dường như nó đang làm thủ thuật :)

1

Nghe có vẻ bẩn nhưng đường đi của kháng cự ít nhất có thể sẽ là để đệm văn bản với khoảng trắng để cho phép cuộn.

Bạn có thể xóa chúng khi nhấp nếu cần.

+0

Tôi xem xét phương pháp này và nó là khá bẩn, nhưng nó sẽ làm công việc. Vấn đề chính là xác định số lượng khoảng trống cần thêm để làm cho nó đạt đến giới hạn cuộn ... – AndroidNoob

+0

Tôi có thể thấy đây là vấn đề với chế độ xem văn bản có kích thước động. Bạn có thể sử dụng mã đệm từ đây: http://stackoverflow.com/questions/388461/how-can-i-pad-a-string-in-java để làm cho nó ngay cả trên cả hai mặt. Sau đó, sử dụng chiều rộng của TextView làm hệ số nhân. Tất cả bẩn thỉu nhưng có vẻ như thậm chí buộc điều này là một chút của một hack. – JodiMiddleton

15

Tạo hoạt ảnh của riêng bạn.

anim/marquee.xml

<?xml version="1.0" encoding="utf-8"?> 
<set xmlns:android="http://schemas.android.com/apk/res/android"> 
    <translate 
     android:fromXDelta="100%" 
     android:toXDelta="-100%" 
     android:duration="10000" 
     android:repeatCount="infinite" 
     android:repeatMode="restart" 
     android:interpolator="@android:anim/linear_interpolator"/> 
</set> 

và trong hoạt động của bạn,

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.my_activity); 

    TextView myTextView = (TextView) findViewById(R.id.myTextView); 
    Animation marquee = AnimationUtils.loadAnimation(this, R.anim.marquee); 
    myTextView.startAnimation(marquee); 
} 
+0

Giải pháp tuyệt vời, tuy nhiên nội suy nên được đặt trong bộ không phải là dịch. – Leon

+0

@karaokyo Textview của văn bản được cắt ở cuối trong khi hiển thị đó là tốt (theo chiều rộng xem), nhưng hình ảnh động cũng cho thấy văn bản cắt ngắn cho hoạt hình thay vì toàn văn. Bạn có thể cho tôi biết lý do tại sao? Nếu tôi đặt textview.setselected thành true thì văn bản đầy đủ sẽ hiển thị trong hoạt ảnh nhưng hoạt ảnh bắt đầu mà không có tương tác của người dùng. –

+0

Hoạt ảnh này không chỉ di chuyển văn bản mà còn là chế độ xem toàn văn. Tôi có một nền đen trên textview và một hoạt động màu trắng. Toàn bộ di chuyển văn bản (với nền) và không chỉ văn bản. –

Các vấn đề liên quan