Android'de TextView'i kaydırılabilir yapma


771

Bir ekrana sığmayacak kadar uzun görünen bir metin görünümünde metin görüntülüyorum. TextView öğemi kaydırılabilir yapmam gerekiyor. Bunu nasıl yapabilirim?

İşte kod:

final TextView tv = new TextView(this);
tv.setBackgroundResource(R.drawable.splash);
tv.setTypeface(face);
tv.setTextSize(18);
tv.setTextColor(R.color.BROWN);
tv.setGravity(Gravity.CENTER_VERTICAL| Gravity.CENTER_HORIZONTAL);
tv.setOnTouchListener(new OnTouchListener() {
    public boolean onTouch(View v, MotionEvent e) {
        Random r = new Random();
        int i = r.nextInt(101);
        if (e.getAction() == e.ACTION_DOWN) {
            tv.setText(tips[i]);
            tv.setBackgroundResource(R.drawable.inner);
        }
        return true;
    }
});
setContentView(tv);

Yanıtlar:


1720

ScrollViewAslında kullanmanıza gerek yok .

Sadece

android:scrollbars = "vertical"

aramalarınızdan özellikleri TextViewsizin Düzenin xml dosyasında.

Sonra kullan:

yourTextView.setMovementMethod(new ScrollingMovementMethod());

kodunuzda.

Bingo, kayar!


96
Ancak, kesinlikle maxLinesrastgele bir sayı girmenizi gerektirir; bu her ekran boyutu ve yazı tipi boyutu için işe yarayacak bir şey değil mi? Ben sadece bir ile sarmak için daha basit buluyorum ScrollView, yani (XML yöntemini ayarlamak gibi) başka XML öznitelikleri veya kod eklemek zorunda değilsiniz.
Christopher Orr

12
@Christopher, ScrollView 'android: layout_height' gerektirir.
Regex Çaylak

11
@ Regex: Evet. Gerek ScrollViewduyduğu kadar yer kaplamasına izin verirsiniz (örneğin, android:fillViewportöznitelik yoluyla ) veya istediğiniz boyutu ayarlarsınız. maxLinesUI öğelerinin boyutlarını ayarlamak için kullanmak kullanılmamalıdır, bu nedenle çözüm yoktur.
Christopher Orr

62
maxlines tanımlamanız gerekmez. sadece geri kalanı.
Stevanicus

13
Herkesin "yumuşak" kaydırma hakkında söylediklerini açıklığa kavuşturmak için: Bu yöntemi kullanırsanız kaydırma aslında "yumuşak" olur (pikselleri piksel piksel kaydırabilirsiniz), ancak kinetik değildir . Parmağınızı kaldırır kaldırmaz anında kaydırmayı durdurur - titreşim olmaz. Bu, modern bir kullanıcı arayüzü için oldukça kabul edilemez, bu yüzden diğer insanların bu "çözüm" için zaman kaybetmediğinden emin olmak için cevabı düzenleyeceğim.
Timmmm

310

Ben tamamen XML bunu yaptım:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <ScrollView
        android:id="@+id/SCROLLER_ID"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical"
        android:fillViewport="true">

        <TextView
            android:id="@+id/TEXT_STATUS_ID"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_weight="1.0"/>
    </ScrollView>
</LinearLayout>

NOTLAR:

  1. android:fillViewport="true"ile birleştirildiğinde android:layout_weight="1.0"metin görünümü kullanılabilir tüm alanı kaplar.

  2. Kaydırma Görünümü'nü tanımlarken, android:layout_height="fill_parent"aksi takdirde kaydırma görüntüsü çalışmaz! (bu benim bir saatimi boşa harcamama neden oldu! FFS).

PRO İPUCU:

Metin ekledikten sonra programlı olarak en alta kaydırmak için şunu kullanın:

mTextStatus = (TextView) findViewById(R.id.TEXT_STATUS_ID);
mScrollView = (ScrollView) findViewById(R.id.SCROLLER_ID);

private void scrollToBottom()
{
    mScrollView.post(new Runnable()
    {
        public void run()
        {
            mScrollView.smoothScrollTo(0, mTextStatus.getBottom());
        }
    });
}

12
Kullanmaya gerek yoktur mTextView.getBottom(), sadece mScrollView.fullScroll(View.FOCUS_DOWN)ScrollView API'sinin bir parçası olduğu için yöntemi kullanın . Daha fazla bilgi için buraya ve buraya bakın .
ChuongPham

7
Android , bu örnekte ya da LinearLayoutya ScrollViewda yararsız olabileceği konusunda uyarıyor ( LinearLayouttamamen kaldırdım ). Ayrıca TextView, bunun android:layout_height="wrap_content"için eşleşmesi gerektiği konusunda da uyarır ScrollView. Bu uyarılar, bu yanıtın gönderilmesinden bu yana geçen 3 yıl nedeniyle olabilir. Ne olursa olsun, bu cevap düzgün kaydırma ve kaydırmayı destekler ... + 1
skia.heliou

<!--suppress AndroidLintUselessParent -->Yukarıdaki ScrollViewxml dosyasına eklemek , bu uyarıları dikkate alır.
Louie Bertoncin

Android API düzey 9'da "profesyonel ipucu" benim için çalışmaz.
LarsH

Bu yaklaşım çok daha iyi kabul edilmiş cevap yaklaşımını kullanarak sorunsuz bir kullanıcı deneyimi üretmeyecektir.
seyedrezafar

120

Gerçekten gerekli olan tek şey setMovementMethod (). İşte LinearLayout kullanan bir örnek.

Main.xml dosyası

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView
    android:id="@+id/tv1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:text="@string/hello"
    />
</LinearLayout>

WordExtractTest.java Dosyası

public class WordExtractTest extends Activity {

    TextView tv1;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

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

        loadDoc();
    }

    private void loadDoc() {

        String s = "";

        for(int x=0; x<=100; x++) {
            s += "Line: " + String.valueOf(x) + "\n";
        }

        tv1.setMovementMethod(new ScrollingMovementMethod());

        tv1.setText(s);
    }
}

3
Bu özelliği XML olarak ayarlamanın bir yolu var mı? Acaba neden bu seçeneği terkedecekler.
Thalur

Çalışıyor ama kaydırma yaptıktan sonra yenilemek için herhangi bir yolu var mı? TextView kaydırdıktan sonra üzerinde metin değiştireceğim, ama gerekli olmasa bile konumu kaydırılır kalır. onun bcose daha önce kaydırma uygulamıştı ...
Nirav Dangi

9
kaydırma çubukları yoktur ve kaydırma, ScrollViewyönteme kıyasla karmaşıktır .
Jeffrey Blattman

1
Bir StringBuilderyerine kullanın String... sahip olduğunuz biraz israf.
Alex Lockwood

4
Bu işe yarar ancak kaydırma düzgün değildir. Yine de teşekkürler çalışıyor.
ayaz


41

Koymak gerekli değildir

android:Maxlines="AN_INTEGER"`

Sadece şunları ekleyerek çalışmanızı yapabilirsiniz:

android:scrollbars = "vertical"

Ve bu kodu Java sınıfınıza ekleyin:

textview.setMovementMethod(new ScrollingMovementMethod());

Kaydırma çubuğu boyutu metne tam olarak uyduğundan ve alanınızı boşa harcamadığınız için, kabul edilenden çok daha iyi bir çözüm.
FractalBob

ScrollView'ı ebeveyn olarak kullandığımda, o zaman çalışmıyor
Prens

27

Ya sen

  1. çevreleyen TextViewbir yan ScrollView; veya
  2. Hareket yöntemini olarak ayarlayın ScrollingMovementMethod.getInstance();.

22

Bulduğum en iyi yol:

TextView öğesini aşağıdaki ekstra niteliklerle bir EditText ile değiştirin:

android:background="@null"
android:editable="false"
android:cursorVisible="false"

ScrollView içinde kaydırma yapmaya gerek yoktur.


2
Kolayca en iyi ve en uygun cevap, özellikle EditText'in bir TextView alt sınıfı olduğu ve sorunun nasıl çözüleceğinin değil, metin görünümünün kaydırılabilir hale getirilmesidir. Eğer yapabilseydim iki kez oy
verirdim

4
@JustinBuser Daha fazla anlaşamadım. :) Bunun işe yaraması tamamen tesadüfidir ve Android'in gelecekteki sürümlerinde olacağının garantisi yoktur. Kaydırma yapmak istiyorsanız, Android'in sağladığı kaydırma araçlarını kullanın. ScrollViewdoğru yol.
Madbreaks

1
@Madbreaks Bu konuda "tesadüfi" bir şey yok, EditText birkaç farklı yöntem ve geçersiz kılınan uzunluk metnini barındıracak şekilde uyarlanmış bir geçersiz kılma özelliğine sahip bir TextView IS. Özellikle EditText, TextView getDefaultMovementMethod işlevi için dönüş değerini geçersiz kılar. Varsayılan uygulama NULL döndürür, EditText temelde tüm diğer cevapların önerdiği şeyi yapar. Android'in sağladığı araçları kullanmakla ilgili olarak, EditText sınıfının bu cevaplarda bulunan diğer yöntemlerden herhangi birine göre kullanımdan kaldırılma olasılığı daha düşüktür.
Justin Buser

4
@JustinBuser Benim sorunum olsa EditText varsayılan davranışına bağlı olduğunu, yani çok iyi yolda aşağı değiştirmek anlamına geliyordu (hiç EditText kullanımdan kaldırılacak). Ancak yine de fikir, eldeki göreve uygun bileşenler ve özellikler kullanmak olduğunu iddia edebilirsiniz. ScrollView açıkça kaydırmayı kapsayacak şekilde tasarlanmıştır. Her zaman yapmaya çalışırım ve her zaman başkalarının iş için doğru aracı kullanmasını öneririm. Herhangi bir programlama problemine neredeyse her zaman birçok yaklaşım vardır. Her neyse, düşünceli yanıt için teşekkürler.
Madbreaks

16

Basit. Ben böyle yaptım:

  1. XML Tarafı:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        tools:context="com.mbh.usbcom.MainActivity">
        <TextView
            android:id="@+id/tv_log"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:scrollbars="vertical"
            android:text="Log:" />
    </RelativeLayout>
  2. Java tarafı:

    tv_log = (TextView) findViewById(R.id.tv_log);
    tv_log.setMovementMethod(new ScrollingMovementMethod());

Bonus:

Metin görünümünün metin doldururken aşağı kaydırmasına izin vermek için şunları eklemeniz gerekir:

    android:gravity="bottom"

TextView xml dosyasına. Daha fazla metin geldikçe otomatik olarak aşağı kayar.

Elbette, metni set metni yerine ekleme işlevini kullanarak eklemeniz gerekir:

    tv_log.append("\n" + text);

Log amaçlı kullandım.

Umarım bu yardımcı olur ;)


14

Bu, yalnızca XML kullanarak "ScrollBar'ı TextView öğenize nasıl uygularsınız" dır.

İlk olarak, main.xml dosyasında bir Textview denetimi almanız ve içine bir metin yazmanız gerekir ... şöyle:

<TextView
    android:id="@+id/TEXT"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:text="@string/long_text"/>

Ardından, bu metin için kaydırma çubuğunu görüntülemek üzere metin görünümü denetimini kaydırma görünümü arasına yerleştirin:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent">

    <ScrollView
        android:id="@+id/ScrollView01"
        android:layout_height="150px"
        android:layout_width="fill_parent">

        <TextView
            android:id="@+id/TEXT"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:text="@string/long_text"/>

    </ScrollView>
</RelativeLayout>

Bu kadar...


6
Bunu neden yazıyorsun? Bu, siz yazmadan 6 ay önce gönderilen bir cevabın neredeyse aynı, daha az doğru olsa da bir versiyonudur.
Justin Buser

11

Bu, kaydırma çubuğuyla düzgün kaydırma metni sağlar.

ScrollView scroller = new ScrollView(this);
TextView tv = new TextView(this);
tv.setText(R.string.my_text);
scroller.addView(tv);

Mavi animasyonu etkinleştirir. En iyi cevap burada IMO.
Griffin W.

11

Someone Somewhere (yukarıdaki Android'de TextView'i kaydırılabilir yapma) üstündeki "profesyonel ipucu" harika çalışıyor, ancak ScrollView'a dinamik olarak metin ekliyorsanız ve yalnızca kullanıcı şu anda eklendikten sonra otomatik olarak alta kaydırmak isterseniz ne olur? ScrollView? (Belki de kullanıcı bir şeyi okumak için yukarı kaydırdıysa, bir ekleme sırasında otomatik olarak en altına sıfırlamak istemezsiniz, bu da can sıkıcı olacaktır.)

Her neyse, işte burada:

if ((mTextStatus.getMeasuredHeight() - mScrollView.getScrollY()) <=
        (mScrollView.getHeight() + mTextStatus.getLineHeight())) {
    scrollToBottom();
}

MTextStatus.getLineHeight () işlevi, kullanıcı ScrollView'un sonundan itibaren bir satırdaysa scrollToBottom () işlevini kullanmamanızı sağlar.


10

Metnin metin görünümünde kaydırılmasını istiyorsanız, aşağıdakileri takip edebilirsiniz:

Öncelikle metin görünümünü alt sınıflara ayırmanız gerekir.

Ve sonra bunu kullan.

Aşağıda, bir alt sınıf metin görünümüne örnek verilmiştir.

public class AutoScrollableTextView extends TextView {

    public AutoScrollableTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setEllipsize(TruncateAt.MARQUEE);
        setMarqueeRepeatLimit(-1);
        setSingleLine();
        setHorizontallyScrolling(true);
    }

    public AutoScrollableTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setEllipsize(TruncateAt.MARQUEE);
        setMarqueeRepeatLimit(-1);
        setSingleLine();
        setHorizontallyScrolling(true);
    }

    public AutoScrollableTextView(Context context) {
        super(context);
        setEllipsize(TruncateAt.MARQUEE);
        setMarqueeRepeatLimit(-1);
        setSingleLine();
        setHorizontallyScrolling(true);
    }

    @Override
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
        if(focused)
            super.onFocusChanged(focused, direction, previouslyFocusedRect);
    }

    @Override
    public void onWindowFocusChanged(boolean focused) {
        if(focused)
            super.onWindowFocusChanged(focused);
    }

    @Override
    public boolean isFocused() {
        return true;
    }
}

Şimdi, bunu XML'de şu şekilde kullanmalısınız:

 <com.yourpackagename.AutoScrollableTextView
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:text="This is very very long text to be scrolled"
 />

Bu kadar.


7

XML'deki metin görünümüne aşağıdakileri ekleyin.

android:scrollbars="vertical"

Ve son olarak,

textView.setMovementMethod(new ScrollingMovementMethod());

Java dosyasında.


1
Bu kinetik kaydırma yapmaz. Bunu kullanma.
Timmmm

6

Bir yukarı veya aşağı kaydırma hareketinden sonra kaydırma devam ediyor 'fling' jestini desteklemek için TextView kaydırma bulamadık. Kendimi uyguladım çünkü çeşitli nedenlerle bir ScrollView kullanmak istemedim ve hem metin seçmeme hem de bağlantıları tıklamama izin veren bir MovementMethod yoktu.


6
soo ... kaçış hareketini nasıl ekledin?
Lou Morda

6

Kotlin'de metin görünümünü kaydırılabilir yapmak için

myTextView.movementMethod= ScrollingMovementMethod()

ve ayrıca xml içine bu özelliği ekleyin

    android:scrollbars = "vertical"

5

Kaydırılabilir işleminiz bittiğinde, görünüme herhangi bir şey girdiğinizde bu satırı görünümün son satırına ekleyin:

((ScrollView) findViewById(R.id.TableScroller)).fullScroll(View.FOCUS_DOWN);

ahbap, tablescroller işlenmiş XML id niteliği tarafından belirlenen bir görünümdür .. u sadece deneyin .. o iyi çalışır .. bana çalışır onun iş ..
Rahul Baradia

4

EditText çözümünü kullanmak istemiyorsanız, daha iyi şansınız olabilir:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.yourLayout);
    (TextView)findViewById(R.id.yourTextViewId).setMovementMethod(ArrowKeyMovementMethod.getInstance());
}

4

Bunu XML düzeninize ekleyin:

android:ellipsize="marquee"
android:focusable="false"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:text="To Make An textView Scrollable Inside The TextView Using Marquee"

Ve kodda aşağıdaki satırları yazmalısınız:

textview.setSelected(true);
textView.setMovementMethod(new ScrollingMovementMethod());

2
Bu kinetik kaydırma yapmaz. Bunu kullanma.
Timmmm

bitiş metnini elips etmek istemiyorum. nasıl yaparım.
Sagar Nayak

@SagarNayak android kullanın: ellipsize = "none"
Francis

2

Aşağıdaki kod, otomatik yatay kaydırma metin görünümü oluşturur:

Xml kullanımına TextView eklerken

<TextView android:maxLines="1" 
          android:ellipsize="marquee"
          android:scrollHorizontally="true"/>

OnCreate () öğesinde aşağıdaki TextView özelliklerini ayarlayın

tv.setSelected(true);
tv.setHorizontallyScrolling(true); 


1

Bu şekilde kullanın

<TextView  
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:maxLines = "AN_INTEGER"
    android:scrollbars = "vertical"
/>

0

Benim durumumda kısıtlama düzeni AS 2.3.

Kod uygulaması:

YOUR_TEXTVIEW.setMovementMethod(new ScrollingMovementMethod());

XML:

android:scrollbars="vertical"
android:scrollIndicators="right|end"

0

Bir haftadan fazla bir süre bununla mücadele ettim ve nihayet bu işin nasıl yapılacağını anladım!

Benim sorunum her şeyin bir 'blok' olarak kaydırılacağıydı. Metnin kendisi kayıyor, ancak satır satır değil, yığın olarak. Bu benim için işe yaramadı, çünkü alt kısımdaki çizgileri kesecekti. Önceki çözümlerin hepsi benim için işe yaramadı, bu yüzden kendi çözümlerimi hazırladım.

Şimdiye kadarki en kolay çözüm:

Bir paketin içinde 'PerfectScrollableTextView' adlı bir sınıf dosyası oluşturun, ardından bu kodu kopyalayıp içine yapıştırın:

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.TextView;

public class PerfectScrollableTextView extends TextView {

    public PerfectScrollableTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setVerticalScrollBarEnabled(true);
        setHorizontallyScrolling(false);
    }

    public PerfectScrollableTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setVerticalScrollBarEnabled(true);
        setHorizontallyScrolling(false);
    }

    public PerfectScrollableTextView(Context context) {
        super(context);
        setVerticalScrollBarEnabled(true);
        setHorizontallyScrolling(false);
    }

    @Override
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
        if(focused)
            super.onFocusChanged(focused, direction, previouslyFocusedRect);
    }

    @Override
    public void onWindowFocusChanged(boolean focused) {
        if(focused)
            super.onWindowFocusChanged(focused);
    }

    @Override
    public boolean isFocused() {
        return true;
    }
}

Son olarak 'TextView' öğenizi XML'de değiştirin:

Gönderen: <TextView

Kime: <com.your_app_goes_here.PerfectScrollableTextView


1
% 100 Mükemmel cevap. Açıklamasında bahsettiğinizle aynı sorunla karşılaştım. birçok çözüm uygulayın ancak mükemmel çalışmaz. ama çözümünüz her durumda mükemmel çalışıyor. kurtarmak benim zaman adam :) Teşekkürler
Daxesh Vekariya

@DaxeshVekariya Sizin için çalıştı sevindim!
Petro

0

Put maxLinesve scrollbarsxml TextView içeride.

<TextView android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:scrollbars="vertical"
    android:maxLines="5" // any number of max line here.
    />

Sonra java kodunda.

textView.setMovementMethod(new ScrollingMovementMethod());


0

TextViewİçinde kullanırken bu sorunu yaşadımScrollView . Bu çözüm benim için çalıştı.

scrollView.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {

                description.getParent().requestDisallowInterceptTouchEvent(false);

                return false;
            }
        });

        description.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {

                description.getParent().requestDisallowInterceptTouchEvent(true);

                return false;
            }
        });

0

ScrollView'ı üst öğe olarak kullanmanız gerektiğinde Ve ayrıca TextView ile kaydırma hareketi yöntemini de kullanırsınız.

Ve cihazınızı yatay konuma getirmek için portre yaptığınızda bazı sorunlar ortaya çıkar . (gibi) tüm sayfa kaydırılabilir ancak kaydırma hareketi yöntemi çalışmaz.

ScrollView'ı yine de üst öğe veya kaydırma hareketi yöntemi olarak kullanmanız gerekiyorsa, ayrıca desc.

Herhangi bir sorununuz yoksa, TextView yerine EditText'i kullanırsınız

aşağıya bakınız :

<EditText
     android:id="@+id/description_text_question"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:background="@null"
     android:editable="false"
     android:cursorVisible="false"
     android:maxLines="6"/>

Burada, EditText TextView gibi davranır

Ve sorununuz çözülecek


0

XML - android:scrollHorizontallyÖzniteliği kullanabilirsiniz

Metnin görünümden daha geniş olmasına izin verilip verilmediği (ve bu nedenle yatay olarak kaydırılabilir).

"True" veya "false" gibi bir boole değeri olabilir.

Prigramakali - setHorizontallyScrolling(boolean)


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.