In my main layout xml file I have this:
<view class="com.mysite.MainActivity$MySeekBar"
android:id="#+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
And in MainActivity.java inside the MainActivity class I have this:
public static class MySeekBar extends SeekBar {
public MySeekBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
}
In the above case, nothing displays. However it does work if instead of the first snippet I have this:
<SeekBar
android:id="#+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
I have also tried using uppercase 'View' instead of 'view' in the xml.
What am I doing wrong?
Edit: I have tried following this google developer page on custom components which at the bottom gives a simple example of implementing with an inner class.
put this class in its own file
<com.mypackagename.MySeekBar <== this is missing
android:id="#+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
In my app I have a very basic looking compass which is rendered within my activity through a class. I am trying to display the compass with a layout. So rather than having just a circle with a line pointing north, I can include text box and buttons. How do I render this within a layout? Currently my activity sets the content view like so:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
compassView = new CompassView(this);
setContentView(compassView);
I have tried setContentView(R.layout.activity_display_compass) which is my xml file however it only display "hello world" (the TextView), not the compass. See my xml file below.
xml
<LinearLayout 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:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world"/>
<View
class = "com.example.gpsfinder.CompassView"
android:id="#+id/compassView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Any guidance would be greatly appreciated.
To use a custom View subclass in your xml layout file:
<LinearLayout 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:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world"/>
<com.example.gpsfinder.CompassView
android:id="#+id/compassView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
And then you probably need to add some of these constructors in your Java code:
// you used this ctor when creating the view programmatically
public CompassView(Context context) {
this(context, null);
// add additional initialization here
}
// this constructor is needed for the class to be used in XML layout files!
public CompassView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
// add additional initialization here
}
// this constructor is needed for the class to be used in XML layout files,
// with a class-specific base style
public CompassView(Context context, AttributeSet attributeSet, int defStyle) {
super(context, attributeSet, defStyle);
// add additional initialization here
}
I know there are dozens similar post, but it looks to me everything is correct here:
The custom widget:
public class DoubleTextItem extends LinearLayout {
private TextView txtMain;
private TextView txtDescription;
public DoubleTextItem(Context context) {
super(context);
}
public DoubleTextItem(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
((Activity)getContext()).getLayoutInflater().inflate(R.layout.widget_double_text_item, this);
setupViewItems();
}
private void setupViewItems() {
txtMain = (TextView) findViewById(R.id.txtMain);
txtDescription = (TextView) findViewById(R.id.txtDecription);
}
public void setDescription(String text) {
txtDescription.setText(text);
}
}
The custom widget layout xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/txtMain"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/txtDecription"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
ANd here inside an activity function i get a casting error,
LayoutInflater inflater = LayoutInflater.from(this);
DoubleTextItem item = (DoubleTextItem) inflater.inflate(R.layout.widget_double_text_item, layout);
item.setText(som-txt);
item.setDescription("#"+athlete.getString("position"));
Here, the root View is a LinearLayout but you try to cast it your custom class:
DoubleTextItem item = (DoubleTextItem) inflater.inflate(R.layout.widget_double_text_item, layout);
The standard advice is:
All DoubleTextItems are LinearLayouts, but not all LinearLayouts are DoubleTextItems.
Meaning you cannot downcast objects from a LinearLayout to a DoubleTextItem, there are too many assumptions and Java won't let you do it.
If you want a DoubleTextItem in your layout you need to use:
<your.package.name.DoubleTextItem
... />
(Also, calling inflate inside onFinishInflate() seems a little silly especially since you don't save the inflated item... If you want to inflate a different layout, don't inflate the first one.)
Overall it looks like you are trying to recreate the now deprecated TwoLineListItem, perhaps you can learn some pointers from it's source code (or just use the TwoLineListItem.)
I've been reading a lot of similar questions to try and find the solution for this but with no luck.
MainActivity.java
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.game);
}
game.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" >
<View
android:id="#+id/adView"
android:background="#drawable/ad"
android:layout_width="320dp"
android:layout_height="50dp"
/>
<my.package.MainGamePanel
android:id="#+id/gameView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/> </RelativeLayout>
MainGamePanel.java
public class MainGamePanel extends SurfaceView implements SurfaceHolder.Callback {
private MainThread thread;
public MainGamePanel(Context context, AttributeSet a) {
super(context, a);
View.inflate(context, R.layout.game, null);
onFinishInflate();
thread = new MainThread(getHolder(), this);
setFocusable(true);
thread.setRunning(true);
etc. etc.
And then outside the MainGamePanel constructor is the function:
#Override
protected void onFinishInflate() {
getHolder().addCallback(this);
}
There is also a MainThread.java file but I don't think that is the problem.
This is the runtime exception:
java.lang.RuntimeException: Unable to start activity ComponentInfo{my.package/my.package.MainActivity}: android.view.InflateException: Binary XML file line #13: Error inflating class my.package.MainGamePanel
If I change the setContentView in MainActivity to setContentView(new MainGamePanel(this)) and remove the AttributeSet parameter from the constructor, and delete the View.Inflate(context, R.layout.game, null); , then it works, but I want to figure out how to use the custom view in the xml file.
it looks like you are circularly inflating layouts. you setContentView on R.layout.game, which contains a MainGamePanel, which inflates R.layout.game, which contains a MainGamePanel, etc.
you should take the View.inflate line out of the onCreate method. It's not doing anything anyway, as far as I can see. you also shouldn't explicitly call onFinishInflate. That will be called automatically when the inflation of the MainGamePanel instance is actually finished.
I have PreferencesActivity which I need it to be right aligned because I want to use Arabic language, I tried to use android:layout_gravity="right" for PreferenceScreen but it didn't work.
This is my 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>
This is how I use the XML inside PreferencesActivity:
addPreferencesFromResource(R.layout.preferences);
After spending some time searching about our shared question, I found nothing useful. obviosly android api doesn't support RTL prefefrences. it means no support for persian/hebrew/arabic languages. But afterall I tried to find some way to right align an editText. I drived EditTextPreference class and implemented onCreateView method again.
here is my code:
/**
* 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;
}
}
the rest of the preferences in the standard android api should be the same(btw I haven't tried yet).
maybe someday we should fully implement rtl support in android preferences and host it on github.
Hope this code snippet helps you.
Unfortunately the base Preference components (PreferenceScreen, Preference, etc.) are implemented in a fairly non-configurable way. They are designed to work in a specific way and are not terribly customizable.
In order to do what you want, you will probably have to implement your own version of PreferenceScreen (or possible just the Preference types you are using such as CheckBoxPreference). The way it is designed, when it inflates XML layouts it assumes a lot of things about them and handles it for you (text size, padding, layout, wrapping, etc). This is great if you want it to look like the default, but not so great if you need to tweak these configurations.
(note: if you don't want to implement preferencescreen you could just use a listview and treat it as a preference page. However, either way you basically have to implement your own version of preferences.)
(note2: based on other questions I've seen about arabic text, it's POSSIBLE android is smart enough to try to right align it by default. However, I would be surprised if this was the case. Still, it's worth a try.)
Sorry I don't have a better answer for you.
In your manifest file under application tag add this line,
android:supportsRtl="true"
After checking for a few solutions i came upon something that might help.
It's not elegant and works only on 4 and up but it's better than nothing...
add this code to 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());
Of course you can choose to change the locale in your preference activities onResume() method only in your MainActivity's onResume() change locale back to your preferred (or user defined) locale.
Hope this helps!
Alright, this might be quite late, but anyways if you are targeting Android 3.0 or higher, you should use PreferenceFragment with can be somehow made RTL.
So you should create a fragment in your code like this:
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);
}
}
now you should create an Activity that adds this fragment to its layout.
You can create a layout for your activity and put the fragment in it via xml element or using the FragmentManager class. But the key to make the preferences Right-To-Left is to put a layout_direction="rtl" attribute in the layout file for a parent element of the fragment. i.e.
<?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>
Notice the android:layoutDirection="rtl" on the RelativeLayout element that fixes the problem.
Now add the Activity Java code like any other activity and add to your manifest file.
Hope it's not too late :)
same as my problem and this is the solution:
inside your 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) {
}
});
}
the result is like this image:right to left Preference
In my point of view this can be the solution:
Set each view's LayoutDirection to 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;}
for preferences fragment you can make its container to have this attribute
android:layoutDirection="rtl"
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;
}
}
create a layout xml file called preference_checkbox.xml paste this (change the color 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.
You could do that by using a custom layout with calling setLayoutResource(int layoutResId).
res/layout/preference_layout.xml: (Note that this is based on HoloEverywhere library org.holoeverywhere.preference.Preference)
<?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>
In your custom Preference:
#Override
protected View onCreateView(ViewGroup parent)
{
setLayoutResource(R.layout.preference_layout);
return super.onCreateView(parent);
}
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;
}
}
This method worked for me:
#Override
public View onCreateView(View parent, String name, Context context, AttributeSet attrs)
{
View v = super.onCreateView(parent, name, context, attrs);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
{
if(parent != null)
parent.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
if(v != null)
v.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
}
return v;
}
Arabic text has posed a problem for many a user which means that similar, if not the same, questions have been answered several times.
I'll just leave these here
Android Arabic text aligment and
How to support Arabic text in Android?