0

I'm laying out an app which presents the results of a search in a ListView. I've defined each item to have a custom layout as follows:

<?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>

This looks great when subtitle and date are of appropriate length to fit on a single line, however it looks awful if the subtitle consumes most of the line and forces date to take a very thin width and so wrap vertically.

What I'd like to do is have them appear side-by-side when there's space but on separate lines if there isn't. I've tried fiddling with the various layout_* attributes and the gravity to no avail and the question isn't very Google-able (at least, I can't think of the right words to search for). Can anyone point me towards the combination of layout rules that I need to achieve this? Or perhaps a different container if one would be more appropriate?

4

2 に答える 2

1

以下のコードはあなたが望むことをすると思いますが、xml レイアウトでのみこれを行う方法がわかりません。基本的に、あなたが探していると思われる2つの異なるレイアウトオプションを持つ2つの異なるTextViewにtextChangedListenerを追加しました。両方とも、テキストビューを表示する日付を持つ独自の相対的なレイアウト内にあります。サブタイトルが設定されている場合、これらの最初のものはテキストを保持するために使用され、複数行が必要な場合は 2 番目の 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>

テキストビュー切り替えロジックを含むメイン アクティビティ コード:

    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

あなたのレイアウトでは、アイテムごとに 2 つのビュー (サブタイトルと日付) を定義します。1 つは同じ行に、もう 1 つはその下の行にあります。次に、これら 2 つのフィールド (またはそれらの合計) の長さを確認し、次のコードを記述します。

 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 に答える