2013-04-29 4 views
0

Я выкладываю приложение, которое представляет результаты поиска в ListView. Я определил каждый элемент, чтобы иметь пользовательский макет следующим образом:Android RelativeLayout - показывать элементы бок о бок, когда пространство, но на отдельных линиях, когда недостаточно места?

<?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_ * и гравитацией безрезультатно, и вопрос не очень подходит Google (по крайней мере, я не могу придумать правильные слова для поиска). Может ли кто-нибудь указать мне на сочетание правил компоновки, которые мне нужны для этого? Или, может быть, другой контейнер, если он будет более уместным?

ответ

1

Я считаю, что следующий код будет делать то, что вы хотите, но я не могу видеть путь сделать это только в макете xml. В основном я добавил textChangedListener в два разных TextViews, которые имеют два разных варианта макета, которые, как я считаю, вы ищете, как внутри их собственного относительного макета, так и с даты, отображающей 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(); 
      }       
     } 
    } 
} 
    } 

Я надеюсь, что это помогает.

+0

Кажется, что это решение, поэтому я согласен. К сожалению, для получения эффекта, который я собираюсь сделать, мне кажется, немного похоже, поэтому я вместо этого установил 'android: maxLines =" 1 "' в день TextView и установил субтитры как 'android: layout_toLeftOf = «@ + id/date» и удалили дату «android: layout_toRightOf =» @ + id/subtitle ». Это означает, что дата всегда находится в одной строке справа, а отступы сохраняют подходящий субтитр, содержащийся в его пятне слева (возможно, потребляя несколько строк). Спасибо вам за решение вашего вопроса :) –

0

В вашем макете я бы определил два вида для каждого элемента (субтитр и дату), один в одной строке и один в строке ниже. Тогда я хотел бы проверить длину этих 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); 
    } 
Смежные вопросы