0

我正在布置一个在 ListView 中显示搜索结果的应用程序。我已将每个项目定义为具有自定义布局,如下所示:

<?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="?android:attr/listPreferredItemHeight"
    android:padding="5dp"
    android:paddingRight="?android:attr/scrollbarSize" >

    <TextView
        android:id="@+id/title"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:ellipsize="end"
        android:textAppearance="?android:attr/textAppearanceSearchResultTitle"
        android:textIsSelectable="false" />

    <TextView
        android:id="@+id/date"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/title"
        android:layout_toRightOf="@+id/subtitle" 
        android:gravity="bottom|right"
        android:textAppearance="?android:attr/textAppearanceSearchResultSubtitle"
        android:textIsSelectable="false" />

    <TextView
        android:id="@+id/subtitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/title"
        android:gravity="bottom|left"
        android:textAppearance="?android:attr/textAppearanceSearchResultSubtitle"
        android:textIsSelectable="false" />

</RelativeLayout>

当字幕和日期的长度适合单行时,这看起来很棒,但是如果字幕占用了大部分行并强制日期采用非常细的宽度并因此垂直换行,则看起来很糟糕。

我想做的是让它们在有空间时并排出现,但如果没有空间,它们会出现在单独的行上。我试过摆弄各种 layout_* 属性和重力无济于事,而且这个问题不是很适合谷歌(至少,我想不出合适的词来搜索)。谁能指出我需要实现这一目标的布局规则组合?或者如果一个更合适的话,也许是一个不同的容器?

4

2 回答 2

1

我相信下面的代码会做你想做的事,但我看不到只有在 xml 布局中才能做到这一点的方法。基本上,我已经将一个 textChangedListener 添加到两个不同的 TextView,它们具有我相信您正在寻找的两种不同的布局选项,它们都在它们自己的相对布局中,日期显示 textview。设置字幕时,第一个用于保存文本,如果它需要多于一行,则使用第二个 TextView,并且在任何一种情况下,另一个都将其可见性选项设置为 GONE。在我的示例中,我使用单独的线程来更改字幕,希望这不会使事情混淆太多。

布局xml如下:

    <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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >

<TextView
    android:id="@+id/title"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:ellipsize="end"
    android:textAppearance="?android:attr/textAppearanceSearchResultTitle"
    android:background="#FF009999"
    android:textIsSelectable="false"
    android:text="@string/my_title" />
<RelativeLayout 
    android:id="@+id/resizingTextContainer"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/title" >
    <TextView
        android:id="@+id/date"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:textAppearance="?android:attr/textAppearanceSearchResultSubtitle"
        android:textIsSelectable="false"
        android:textColor="#FFFFFFFF"
        android:background="#FF000000" />
    <TextView 
        android:id="@+id/subtitle1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_toLeftOf="@+id/date"
        android:textAppearance="?android:attr/textAppearanceSearchResultSubtitle"
        android:textIsSelectable="false"
        android:textColor="#FFFFFF"
        android:background="#FF00FF00" />
    <TextView 
        android:id="@+id/subtitle2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/date"
        android:textAppearance="?android:attr/textAppearanceSearchResultSubtitle"
        android:textIsSelectable="false"
        android:visibility="gone"
        android:textColor="#FFFFFF"
        android:background="#FF00FF00" />    
</RelativeLayout>
<Button 
    android:id="@+id/startTestBtn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/resizingTextContainer"
    android:layout_centerHorizontal="true"
    android:text="Click To Begin"
    />
    </RelativeLayout>

以及带有 textview 切换逻辑的主要活动代码:

    package com.example.code.examples.changelayoutwithtextlength;

    import android.os.Bundle;
    import android.app.Activity;
    import android.text.Editable;
    import android.text.TextWatcher;
    import android.view.Menu;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.TextView;

    public class MainActivity extends Activity {

TextWatcher textChangeDisplayCheck = new TextWatcher(){
    @Override
    public void afterTextChanged(Editable s) {
        // TODO Auto-generated method stub

    }
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count,
            int after) {
        // TODO Auto-generated method stub

    }
    @Override
    public void onTextChanged(CharSequence s, int start, int before,
            int count) {
        displayLatestSubtitle(s);           
    }           
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    TextView DateTextView = (TextView)findViewById(R.id.date);
    DateTextView.setText("29th April 2013");

    Button b = (Button)findViewById(R.id.startTestBtn);
    b.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) 
        {
            v.setEnabled(false);
            Thread thread = new testSubtitleThread();
            thread.start();
        }           
    });

    TextView tv = (TextView)findViewById(R.id.subtitle1);   
    tv.addTextChangedListener(textChangeDisplayCheck);
    TextView tv2 = (TextView)findViewById(R.id.subtitle2);
    tv2.addTextChangedListener(textChangeDisplayCheck);
}

private void displayLatestSubtitle(CharSequence newSubtitle)
{
    TextView tv = (TextView)findViewById(R.id.subtitle1);
    TextView tv2 = (TextView)findViewById(R.id.subtitle2);

    tv.removeTextChangedListener(textChangeDisplayCheck);
    tv2.removeTextChangedListener(textChangeDisplayCheck);

    tv.setVisibility(View.GONE);
    tv2.setVisibility(View.GONE);
    tv2.setText("");
    tv.setText(newSubtitle);

    if(tv.getLineCount() > 1)
    {
        tv.setText("");
        tv2.setText(newSubtitle);
        tv2.setVisibility(View.VISIBLE);
    }
    else
    {
        tv.setVisibility(View.VISIBLE);
    }

    tv.addTextChangedListener(textChangeDisplayCheck);
    tv2.addTextChangedListener(textChangeDisplayCheck);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

public class testSubtitleThread extends Thread
{
    String[] subtitles = new String[] { "a short one", "a really long winded subtitle that will take over more than the allowed space", "tiny",
            "Really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, long.",
            ".....", "text just to long to fit on my device"};

    private android.os.Handler handler = new android.os.Handler()
    {
        @Override             
        public void handleMessage(android.os.Message msg) 
        {                 
            if(msg.what < subtitles.length)
            {
                TextView tv = (TextView)findViewById(R.id.subtitle1);
                tv.setText(subtitles[msg.what]);
            }
            else
            {
                Button b = (Button)findViewById(R.id.startTestBtn);
                b.setEnabled(true);
            }
        }
    };
    @Override
    public void run()
    {   
        for(int i = 0; i <= subtitles.length; i++)
        {
            handler.sendEmptyMessage(i);    
            try 
            {
                Thread.sleep(3000);
            } 
            catch (InterruptedException e) 
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }                           
        }
    }   
}
    }

我希望这有帮助。

于 2013-04-29T14:50:55.550 回答
0

在您的布局中,我将为每个项目(字幕和日期)定义两个视图,一个在同一行中,一个在下面的行中。然后我会检查这两个字段的长度(或它们的总和),然后我会编写这段代码:

 if (length > MAX_LENGTH_OF_LINE) > {
        findViewById(R.id.subtitle_line_below).setVisibility(View.VISIBLE);
        findViewById(R.id.subtitle_same_line).setVisibility(View.GONE);
    } else {
        findViewById(R.id.subtitle_line_below).setVisibility(View.GONE);
        findViewById(R.id.subtitle_same_line).setVisibility(View.VISIBLE);
    }
于 2013-04-29T13:01:01.747 回答