2012-07-04 8 views
13

Mam PreferencesActivity, które muszą być wyrównane, ponieważ chcę używać języka arabskiego, próbowałem użyć android:layout_gravity="right" dla PreferenceScreen, ale nie działa.Jak prawidłowo wyrównać PreferencjeAktywność w systemie Android?

To jest mój XML:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:layout_gravity="right"> 
     <PreferenceCategory android:title="General Settings"> 
       <CheckBoxPreference 
         android:title="Full Screen" 
         android:defaultValue="false" 
         android:summary="Always view as Full Screen" 
         android:key="fullScreenPref" /> 
     <Preference 
       android:title="Report Bugs" 
       android:summary="Notify us for any Bugs or Errors" 
       android:key="bugs"/> 
     <Preference 
       android:title="About" 
       android:summary="Version 1.0.0" 
       android:key="about"/> 
     </PreferenceCategory> 
</PreferenceScreen> 

ten sposób mogę korzystać z XML wewnątrz PreferencesActivity:

addPreferencesFromResource(R.layout.preferences); 
+0

Nie pomoże ci to dzisiaj, ale ostatnio firma Google dokonała ogromnej poprawy w językach pisanych od prawej do lewej. Niestety nie pojawią się na urządzeniach przed JellyBean – Merlin

Odpowiedz

9

Niestety składników uprzywilejowane bazowa (PreferenceScreen, Preference, etc.) są realizowane w dość niefigurowalny sposób. Są zaprojektowane do pracy w określony sposób i nie są strasznie konfigurowalne.

Aby zrobić to, co chcesz, prawdopodobnie będziesz musiał zaimplementować własną wersję PreferenceScreen (lub możliwe tylko typy preferencji, których używasz, takie jak CheckBoxPreference). Sposób, w jaki jest zaprojektowany, kiedy nadmuchuje układy XML, zakłada wiele rzeczy na ich temat i obsługuje je (rozmiar tekstu, dopełnienie, układ, opakowanie itd.). To jest świetne, jeśli chcesz, aby wyglądało jak domyślne, ale nie jest tak wspaniałe, jeśli potrzebujesz zmodyfikować te konfiguracje.

(uwaga:.. Jeśli nie chcą wprowadzić preferencescreen można po prostu użyć ListView i traktować je jako stronę preferencji, jednak tak czy inaczej to w zasadzie trzeba zaimplementować własną wersję preferencji)

(uwaga 2: na podstawie innych pytań, które widziałem o arabskim tekście, jest to POSSIBLE Android jest na tyle sprytny, aby spróbować go wyrównać domyślnie.) Byłbym jednak zdziwiony, gdyby tak było, ale warto spróbować .)

Niestety, nie mam dla ciebie lepszej odpowiedzi.

+3

Już testowałem, Android wystarczająco inteligentny w pewnych rzeczach (Ustawienia ogólne), jeśli piszę je w języku arabskim, wyrównuje się do prawej, ale preferencje pozostają wyrównane do lewej. –

+0

To jest ustawienie domyślne określone przez sposób, w jaki preferencje są zawyżone. Będziesz musiał napisać własną wersję preferencji, jeśli chcesz to zmienić, o ile wiem. – matt5784

+0

Możesz utworzyć swój własny układ preferencji xml i wyrównać tekst w prawo. Spójrz na to: http://stackoverflow.com/questions/7094584/checkboxpreference-with-own-layout – black

-1

Tekst arabski stanowi problem dla wielu użytkowników, co oznacza, że ​​podobne, jeśli nie to samo, pytania zostały udzielone kilka razy.

będę po prostu zostawić je tutaj

Android Arabic text aligment i

How to support Arabic text in Android?

+0

Nie odpowiedziałeś na jego pytanie, a konfiguracje układu użyte w tych pytaniach nie istnieją w PreferenceScreens. – matt5784

+0

Raul, to jest kolejna kwestia, wyrównanie tekstu nie jest tym, o co pytam, jego prawidłowemu wyrównaniu lub właściwej grawitacji układów preferncji. –

+0

Ups! Mój błąd. –

11

Po spędzeniu pewnego czasu na szukanie informacji o naszym wspólnym pytanie, znalazłem nic pożytecznego. obviosly android api nie obsługuje rozszerzeń RTL. oznacza brak wsparcia dla języków perskich/hebrajskiego/arabskiego. Ale ostatecznie próbowałem znaleźć sposób na wyrównanie tekstu editText. Napełniłem klasę EditTextPreference i ponownie zaimplementowałem metodęCreateView. tutaj jest mój kod:

/** 
* Created by omid on 1/12/14. 
*/ 
public class RtlTextPreference extends EditTextPreference { 


    public RtlTextPreference(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    @Override 
    protected View onCreateView(ViewGroup parent) { 
     View view = super.onCreateView(parent); 

     RelativeLayout layout = (RelativeLayout) ((LinearLayout) view).getChildAt(1); 
     layout.setGravity(Gravity.RIGHT); 
     return view; 
    } 
} 

reszta preferencji w standardowym android api powinna być taka sama (btw ja jeszcze nie próbowałem). może pewnego dnia powinniśmy w pełni wdrożyć obsługę rtl w preferencjach Androida i hostować go na github. Mam nadzieję, że ten fragment kodu pomoże.

+0

Próbowałem twoje sugerowane rozwiązanie, To naprawdę wyrównuje mój tekst preferencji do prawej, ale problem polega na tym, że nie robi to samo dla ikony preferencji, która znajduje się po lewej stronie mojego tekstu. Tak więc mój obecny wygląd, że tekst znajduje się na prawym ekranie, a jego ikona znajduje się na większości po lewej stronie ekranu. Czy masz jakieś sugestie, w jaki sposób mogę wyrównać ikonę? –

+0

Nie próbowałem jeszcze, ale przypuszczam, że jeśli znajdziesz odniesienie do skojarzonego ImageView dla obrazu ikony, a następnie, ustawienie layout_alignToParentRight na true będzie działać. bezpośrednio nie masz metody o tej samej nazwie, ale możesz użyć setLayoutParams. zobacz http://stackoverflow.com/questions/4305564/android-layout-right-align –

0

Można to zrobić, używając niestandardowego układu z wywoływaniem setLayoutResource(int layoutResId).

res/layout/preference_layout.xml: (Należy pamiętać, że jest to oparte na bibliotece HoloEverywhere org.holoeverywhere.preference.Preferencja)

<?xml version="1.0" encoding="UTF-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:baselineAligned="false" 
    android:gravity="center_vertical" 
    android:minHeight="?attr/listPreferredItemHeight" 
    android:paddingRight="@dimen/preference_item_padding_side" 
    android:paddingLeft="?android:attr/scrollbarSize" > 

    <LinearLayout 
     android:layout_width="wrap_content" 
     android:layout_height="match_parent" 
     android:gravity="center" 
     android:minWidth="@dimen/preference_icon_minWidth" 
     android:orientation="horizontal" > 

     <ImageView 
      android:id="@+id/icon" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_gravity="center" 
      android:minWidth="48dp" 
      android:contentDescription="@string/emptyString" 
      android:paddingRight="@dimen/preference_item_padding_inner" > 
     </ImageView> 
    </LinearLayout> 

    <RelativeLayout 
     android:layout_width="0dp" 
     android:layout_height="wrap_content" 
     android:layout_weight="1" 
     android:paddingBottom="6dip" 
     android:gravity="right" 
     android:layout_gravity="right" 
     android:paddingLeft="@dimen/preference_item_padding_inner" 
     android:paddingTop="6dip" > 

     <TextView 
      android:id="@+id/title" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:ellipsize="marquee" 
      android:fadingEdge="horizontal" 
      android:gravity="right" 
      android:singleLine="true" 
      android:textAppearance="?android:attr/textAppearanceMedium" > 
     </TextView> 

     <TextView 
      android:id="@+id/summary" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignRight="@id/title" 
      android:gravity="right" 
      android:layout_below="@id/title" 
      android:maxLines="10" 
      android:textAppearance="?android:attr/textAppearanceSmall" 
      android:textColor="?android:attr/textColorSecondary" > 
     </TextView> 
    </RelativeLayout> 

    <LinearLayout 
     android:id="@+id/widget_frame" 
     android:layout_width="wrap_content" 
     android:layout_height="match_parent" 
     android:gravity="center" 
     android:minWidth="@dimen/preference_widget_width" 
     android:orientation="vertical" > 
    </LinearLayout> 

</LinearLayout> 

W niestandardowym Preference:

@Override 
protected View onCreateView(ViewGroup parent) 
{ 
    setLayoutResource(R.layout.preference_layout); 

    return super.onCreateView(parent); 
} 
5

W swoim pliku manifestu pod tagiem aplikacji dodać tę linię,

android: supportsRtl = "true"

+0

Ten atrybut jest używany tylko w API 17 i wyżej, ale dobry punkt. –

3

Po sprawdzeniu kilka rozwiązań natknąłem się na coś, co może pomóc. To nie jest elegancki i działa tylko na 4 i do góry, ale lepsze to niż nic ...

dodać ten kod do onResume()

Locale locale = new Locale("iw");// Hebrew in this case 
    Locale.setDefault(locale); 
    Configuration config = new Configuration(); 
    config.locale = locale; 
    getBaseContext().getResources().updateConfiguration(config, 
      getBaseContext().getResources().getDisplayMetrics()); 

Oczywiście możesz zmienić ustawienia regionalne w swoich działaniach uprzywilejowanych Metoda onResume() tylko w opcji onResume() w MainActivity zmienia ustawienia regionalne z powrotem na preferowane (lub zdefiniowane przez użytkownika) ustawienia narodowe.

Mam nadzieję, że to pomoże!

1
create a layout xml file called preference_checkbox.xml paste this (change the colour to what you want, only the gravity and the width set to fill parent are important) : 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" android:layout_height="wrap_content" 
android:minHeight="?android:attr/listPreferredItemHeight" 
android:gravity="center_vertical" android:paddingRight="?android:attr/scrollbarSize"> 

<RelativeLayout android:layout_width="wrap_content" 
    android:layout_height="wrap_content" android:layout_marginLeft="15dip" 
    android:layout_marginRight="6dip" android:layout_marginTop="6dip" 
    android:layout_marginBottom="6dip" android:layout_weight="1"> 

    <TextView android:id="@+android:id/title" 
     android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="right" 
     android:singleLine="true" android:textAppearance="?android:attr/textAppearanceMedium" 
     android:ellipsize="marquee" android:fadingEdge="horizontal" 
     android:textColor=#000000 /> 

    <TextView android:id="@+android:id/summary" 
     android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="right" 
     android:layout_below="@android:id/title" android:layout_alignLeft="@android:id/title" 
     android:textAppearance="?android:attr/textAppearanceSmall" android:textColor=#000000 
     android:maxLines="4" /> 

</RelativeLayout> 

<!-- Preference should place its actual preference widget here. --> 
<LinearLayout android:id="@+android:id/widget_frame" 
    android:layout_width="wrap_content" android:layout_height="match_parent" 
    android:gravity="center_vertical" android:orientation="vertical" /> 

</LinearLayout> 

and then in the preferences xml file for each row in the settings list that you want to right align add this: android:layout="@layout/preference_checkbox" 

thats it! 
got the solution from : http://stackoverflow.com/questions/7094584/checkboxpreference-with-own-layout 
the question there was about check box with image but it's the same technique. 
Good Luck. 
1

porządku, może to być dość późno, ale tak czy inaczej jeśli są kierowane Android 3.0 lub wyższej, należy użyć PreferenceFragment ze można jakoś RTL.

Należy więc stworzyć fragment w kodzie tak:

import android.os.Bundle; 
import android.preference.PreferenceFragment; 

public class SettingsFragment extends PreferenceFragment { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     addPreferencesFromResource(R.xml.preferences); 
    } 
} 

teraz należy utworzyć działanie, które dodaje ten fragment do swojego układu. Możesz utworzyć układ dla swojej aktywności i umieścić w nim fragment za pomocą elementu xml lub używając klasy FragmentManager. Ale kluczem do ustawienia preferencji od prawej do lewej jest umieszczenie atrybutu layout_direction = "rtl" w pliku układu dla elementu macierzystego fragmentu. tj

<?xml version="1.0" encoding="utf-8"?> 

<RelativeLayout 
    android:id="@+id/rootView" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:layoutDirection="rtl" 
    android:orientation="vertical"> 

    <fragment 
     class="blah.blah.SettingsFragment" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content"/> 
</RelativeLayout> 

Zawiadomienie android:layoutDirection="rtl" na elemencie RelativeLayout które rozwiązuje ten problem.

Teraz dodaj aktywność kodu Java, tak jak każdą inną aktywność, i dodaj do pliku manifestu.

nadzieję, że nie jest za późno :)

2
public class RtlEditTextPreference extends EditTextPreference { 

@Override 
protected View onCreateView(ViewGroup parent) { 
    View view = super.onCreateView(parent); 

    RelativeLayout relativeLayout = (RelativeLayout)(((LinearLayout)view).getChildAt(1)); 
    relativeLayout.setGravity(Gravity.RIGHT); 

    TextView title = (TextView) relativeLayout.getChildAt(0); 
    TextView summary = (TextView) relativeLayout.getChildAt(1); 

    RelativeLayout.LayoutParams titleLayoutParams = (RelativeLayout.LayoutParams)title.getLayoutParams(); 
    titleLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); 
    title.setLayoutParams(titleLayoutParams); 

    RelativeLayout.LayoutParams summaryLayoutParams = (RelativeLayout.LayoutParams)summary.getLayoutParams(); 
    summaryLayoutParams.addRule(RelativeLayout.ALIGN_RIGHT, title.getId()); 
    summaryLayoutParams.addRule(RelativeLayout.ALIGN_LEFT, -1); // Override default left alignment to the title 
    summary.setLayoutParams(summaryLayoutParams); 

    return view; 
} 

}

0
public class RtlEditTextPreference extends EditTextPreference { 
public RtlEditTextPreference(Context context, AttributeSet attrs) { 
    super(context, attrs); 
} 

public RtlEditTextPreference(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
} 

public RtlEditTextPreference(Context context) { 
    super(context); 
} 

@Override 
protected View onCreateView(ViewGroup parent) { 
    View view = super.onCreateView(parent); 

    RelativeLayout relativeLayout = (RelativeLayout)(((LinearLayout)view).getChildAt(1)); 
    relativeLayout.setGravity(Gravity.RIGHT); 

    TextView title = (TextView) relativeLayout.getChildAt(0); 
    TextView summary = (TextView) relativeLayout.getChildAt(1); 

    RelativeLayout.LayoutParams titleLayoutParams = (RelativeLayout.LayoutParams)title.getLayoutParams(); 
    titleLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); 
    title.setLayoutParams(titleLayoutParams); 

    RelativeLayout.LayoutParams summaryLayoutParams = (RelativeLayout.LayoutParams)summary.getLayoutParams(); 
    summaryLayoutParams.addRule(RelativeLayout.ALIGN_RIGHT, title.getId()); 
    summaryLayoutParams.addRule(RelativeLayout.ALIGN_LEFT, -1); // Override default left alignment to the title 
    summary.setLayoutParams(summaryLayoutParams); 

    return view; 
} 

}

0

samo jak mojego problemu i jest to rozwiązanie:

wewnątrz PreferenceFragment:

@Override 
    public View onCreateView(LayoutInflater paramLayoutInflater, 
      ViewGroup paramViewGroup, Bundle paramBundle) { 
     getActivity().setTitle(R.string.fragment_title_settings); 
     View v = super.onCreateView(paramLayoutInflater, paramViewGroup, 
       paramBundle); 
     rtlView(v); 
     return v; 
    } 
    public void rtlView(View v){ 
     if(v instanceof ListView){ 
      rtllater((ListView) v); 
     } 
     else 
     if(v instanceof ViewGroup){ 
      if(v instanceof RelativeLayout){ 
       ((RelativeLayout)v).setGravity(Gravity.RIGHT); 
      } 
      else 
      if(v instanceof LinearLayout){ 
       ((LinearLayout)v).setGravity(Gravity.RIGHT); 
      } 
      for (int i=0;i<((ViewGroup)v).getChildCount();i++){ 
       rtlView(((ViewGroup)v).getChildAt(i)); 
      } 
     } 
     else 
      if(v instanceof TextView){ 
       v.getLayoutParams().width=v.getLayoutParams().MATCH_PARENT; 
       ((TextView)v).setGravity(Gravity.RIGHT); 
      } 
    } 
    public void rtllater(ListView v){ 
     v.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() { 
      @Override 
      public void onChildViewAdded(View view, View view1) { 
       rtlView(view1); 
      } 
      @Override 
      public void onChildViewRemoved(View view, View view1) { 

      } 
     }); 
    } 

wynik jest podobny do tego pliku: right to left Preference

0

W mojego punktu widzenia może to być rozwiązanie: Ustaw każdy widok jest LayoutDirection RTL;

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
View view = super.onCreateView(inflater, container, savedInstanceState); 

view.setLayoutDirection(View.LAYOUT_DIRECTION_RTL); 

return view;}