How to solve Error inflating class in Android? - java

I have a custom view that extends the constraint layout as follows :
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/textViewMyTitle"
style="#style/LabelLowLevel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="My Title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/buttonEditMy"
style="#style/InlineButtonTransparent"
android:layout_width="wrap_content"
android:text="#string/edit"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textViewMyTitle" />
<Button
android:id="#+id/buttonPlayMy"
style="#style/InlineButtonHot"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/play"
app:layout_constraintStart_toEndOf="#+id/buttonEditMy"
app:layout_constraintTop_toBottomOf="#+id/textViewMyTitle" />
</androidx.constraintlayout.widget.ConstraintLayout>
The view has some attributes :
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyCard">
<attr name="Mytitle" format="string"/>
<attr name="Mydescription" format="string"/>
<attr name="Myid" format="string"/>
</declare-styleable>
</resources>
And then the corresponding Java class :
public class MyCard extends ConstraintLayout {
public MyCard(#NonNull Context context) {
super(context);
}
public MyCard(#NonNull Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public MyCard(#NonNull Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
public MyCard(#NonNull Context context, #Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context, attrs);
}
public String Description;
public String Topic;
public String MyId;
private void init(Context ctx, AttributeSet attrs) {
TypedArray CustomAttr = ctx.obtainStyledAttributes(attrs, R.styleable.MyCard);
Description = CustomAttr.getString(R.styleable.MyCard_Mydescription);
Topic = CustomAttr.getString(R.styleable.MyCard_Mytitle);
MyId = CustomAttr.getString(R.styleable.MyCard_Myid);
LayoutInflater inflater = (LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.Mycard, this, true); // <<<<<< the error is raised here
CustomAttr.recycle();
}
}
When running the code, I'm getting the error :
java.lang.RuntimeException:
Unable to start activity ComponentInfo{com.colman.myapp/com.colman.myapp.Activity20_PersonalSpace}:
android.view.InflateException: Binary XML file line #49 in com.colman.myapp:layout/activity_activity20_personal_space:
Binary XML file line #49 in com.colman.myapp:layout/activity_activity20_personal_space:
Error inflating class com.colman.myapp.Libraries.views.MyCard
Does anyone know how to solve that please ?
Tthanks.
Cheers

Try to change the way you inflate the layout:
private void init(Context ctx, AttributeSet attrs) {
inflate(ctx, R.layout.Mycard, this);
TypedArray CustomAttr = ctx.obtainStyledAttributes(attrs, R.styleable.MyCard);
Description = CustomAttr.getString(R.styleable.MyCard_Mydescription);
Topic = CustomAttr.getString(R.styleable.MyCard_Mytitle);
MyId = CustomAttr.getString(R.styleable.MyCard_Myid);
CustomAttr.recycle();
}

try to change
inflater.inflate(R.layout.Mycard, this, true);
to
inflater.inflate(R.layout.Mycard, this, false);

Related

How can I set a maximum height for a Scroll View in an Activity?

What I want to achieve:
A java Activity with a belonging xml-layout, where the user can enter the names of all players. Here is how it looks like:
If you click the plus-button you can enter another player (Spieler is german for player). It should be a wrapped view until the maximum height is reached.
I found a very similar question here:
How to set a maximum height with wrap content in android?
There is code given with the comment: "you can add this to any view (override onMeasure in a class inherited from a view)"
Here my question: My belonging java-file to the xml-layout inherits from Activiy thus doesnt know the super.onMeasure() method. Do you have any tipps what I can do? Can I have an Activity-java-file and a View-java-file to one layout? Thanks a lot!
You have to create a custom view that extends ScrollView and then use that view in your xml
public class ScrollViewWithMaxHeight extends ScrollView {
public static int WITHOUT_MAX_HEIGHT_VALUE = -1;
private int maxHeight = WITHOUT_MAX_HEIGHT_VALUE;
public ScrollViewWithMaxHeight(Context context) {
super(context);
init(context, null, 0, 0);
}
public ScrollViewWithMaxHeight(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0, 0);
}
public ScrollViewWithMaxHeight(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs, defStyle, 0);
}
private void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes){
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs, R.styleable.custom_ScrollViewWithMaxHeight, defStyleAttr, defStyleRes);
maxHeight =
a.getDimensionPixelSize(R.styleable.max_height,maxHeight);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
try {
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (maxHeight != WITHOUT_MAX_HEIGHT_VALUE
&& heightSize > maxHeight) {
heightSize = maxHeight;
}
heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.AT_MOST);
getLayoutParams().height = heightSize;
} catch (Exception e) {
LogManager.error(this, "onMesure", "Error forcing height", e);
} finally {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
public void setMaxHeight(int maxHeight) {
this.maxHeight = maxHeight;
}
}
You also have to create an attrs.xml file in your values folder and add this to it.
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<declare-styleable name="custom_ScrollViewWithMaxHeight">
<attr name="max_height" format="dimension" />
</declare-styleable>
</resources>
You can then reference the view like this
<the.package.where.the.view.is.ScrollViewWithMaxHeight
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:max_height="150dp">
</the.package.where.the.view.is.ScrollViewWithMaxHeight>
Its a so simple.
instead of use ScrollView, I prefer you have to use the RecycleView, Adapter and for plus icon use Fab button.
Without creating the custom view and all, you can achieve the maximum hight of RecycleView and bottom with Fab button by using theandroid:layout_height="wrap_content" in your .xml file as
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.tejadroid.testing.MainActivity"
tools:showIn="#layout/app_bar_main">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:paddingBottom="56dp" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|bottom"
android:layout_margin="#dimen/fab_margin"
app:srcCompat="#android:drawable/ic_input_add" />
</FrameLayout>
</RelativeLayout>

CustomView couldn't be instantiated (error in editor preview and nothing shown after compile)

So, I created a CustomView called ButtonWithCaption.xml,
<?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="wrap_content"
android:layout_weight="1"
android:background="?attr/selectableItemBackground"
android:paddingBottom="#dimen/spacing_normal"
android:paddingLeft="#dimen/spacing_small"
android:paddingRight="#dimen/spacing_small"
android:paddingTop="#dimen/spacing_normal">
<ImageView
android:id="#+id/bwc_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginBottom="2dp"
android:scaleType="centerCrop" />
<TextView
android:id="#+id/bwc_caption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/bwc_icon"
android:textAlignment="center" />
Along with its controller ButtonWithCaption.java
public class ButtonWithCaption extends RelativeLayout {
private ImageView mImageView;
private TextView mTextView;
private int mIconSrc;
private String mCaptionText;
private boolean mShowIcon;
private boolean mShowText;
public ButtonWithCaption(Context context) {
super(context);
init(context, null, 0);
}
public ButtonWithCaption(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public ButtonWithCaption(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
private void init(Context context, AttributeSet attrs, int defStyleAttr) {
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ButtonWithCaption, 0, 0);
try {
mIconSrc = a.getResourceId(R.styleable.ButtonWithCaption_iconSrc, 0);
mCaptionText = a.getString(R.styleable.ButtonWithCaption_captionText);
mShowIcon = a.getBoolean(R.styleable.ButtonWithCaption_showIcon, mIconSrc != 0);
mShowText = a.getBoolean(R.styleable.ButtonWithCaption_showText, !mCaptionText.isEmpty());
mImageView = (ImageView) findViewById(R.id.bwc_icon);
mTextView = (TextView) findViewById(R.id.bwc_caption);
mImageView.setImageResource(mIconSrc);
mTextView.setText(mCaptionText);
} finally {
a.recycle();
}
}
}
Nothing fancy.
And then, I declare custom attributes in attrs.xml
<resources>
<declare-styleable name="ButtonWithCaption">
<attr name="iconSrc" format="reference" />
<attr name="captionText" format="string" />
<attr name="showIcon" format="boolean" />
<attr name="showText" format="boolean" />
</declare-styleable>
</resources>
And this is my activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="id.foodmap.foodmapcustomviews.MainActivity">
<id.foodmap.foodmapcustomviews.ButtonWithCaption
android:id="#+id/button_with_caption"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:captionText="Test"
app:iconSrc="#drawable/ic_email_gray_24dp" />
</RelativeLayout>
...but weirdly, Android Studio's preview gave me render error :
Failed to instantiate one or more classes
with stacktrace :
java.lang.NullPointerException
at id.foodmap.foodmapcustomviews.ButtonWithCaption.init(ButtonWithCaption.java:54)
at id.foodmap.foodmapcustomviews.ButtonWithCaption.(ButtonWithCaption.java:29)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.jetbrains.android.uipreview.ViewLoader.createNewInstance(ViewLoader.java:475)
at org.jetbrains.android.uipreview.ViewLoader.loadClass(ViewLoader.java:262)
at org.jetbrains.android.uipreview.ViewLoader.loadView(ViewLoader.java:220)
at com.android.tools.idea.rendering.LayoutlibCallbackImpl.loadView(LayoutlibCallbackImpl.java:186)
at android.view.BridgeInflater.loadCustomView(BridgeInflater.java:334)
at android.view.BridgeInflater.loadCustomView(BridgeInflater.java:345)
at android.view.BridgeInflater.createViewFromTag(BridgeInflater.java:245)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:727)
at android.view.LayoutInflater.rInflate_Original(LayoutInflater.java:858)
at android.view.LayoutInflater_Delegate.rInflate(LayoutInflater_Delegate.java:70)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:834)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
at android.view.LayoutInflater.inflate(LayoutInflater.java:518)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at com.android.layoutlib.bridge.impl.RenderSessionImpl.inflate(RenderSessionImpl.java:324)
at com.android.layoutlib.bridge.Bridge.createSession(Bridge.java:429)
at com.android.ide.common.rendering.LayoutLibrary.createSession(LayoutLibrary.java:368)
at com.android.tools.idea.rendering.RenderTask$2.compute(RenderTask.java:567)
at com.android.tools.idea.rendering.RenderTask$2.compute(RenderTask.java:549)
at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:863)
at com.android.tools.idea.rendering.RenderTask.createRenderSession(RenderTask.java:549)
at com.android.tools.idea.rendering.RenderTask.lambda$inflate$1(RenderTask.java:680)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
My findViewById() from ButtonWithCaption.java to find TextView and ImageView also returns null.
Anyone know what caused this? Because it doesn't even show up in the editor preview window.
P.S. If I use , The preview show the element correctly.
P.S.S. It compiled to my phone with no error, but no ButtonWithCaption shown.
Thanks in advance
You are getting a NullPointerException because you have not inflated the views from ButtonWithCaption.xml. One way to fix this is with the static View.inflate() method:
private void init(Context context, AttributeSet attrs, int defStyleAttr) {
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ButtonWithCaption, 0, 0);
try {
mIconSrc = a.getResourceId(R.styleable.ButtonWithCaption_iconSrc, 0);
mCaptionText = a.getString(R.styleable.ButtonWithCaption_captionText);
mShowIcon = a.getBoolean(R.styleable.ButtonWithCaption_showIcon, mIconSrc != 0);
mShowText = a.getBoolean(R.styleable.ButtonWithCaption_showText, !mCaptionText.isEmpty());
View v = View.inflate(context, R.layout.ButtonWithCaption, this); // add this line
mImageView = (ImageView) findViewById(R.id.bwc_icon);
mTextView = (TextView) findViewById(R.id.bwc_caption);
mImageView.setImageResource(mIconSrc);
mTextView.setText(mCaptionText);
} finally {
a.recycle();
}
}
You have to replace the tag <RelativeLayout> with your class, something like this:
<?xml version="1.0" encoding="utf-8"?>
<com.yourpackage.app.ButtonWithCaption xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
...
>
...
</com.yourpackage.app.ButtonWithCaption>
com.yourpackage.app should be the path where your ButtonWithCaptionclass is.
EDIT:
AYour posted layout sould be your activity layout, the ButtonWithCaptionclass should be your xml element, not your xml name, so change the name, replace the RelativeLayout with your custom class and try it.

can't select with xml id in android

As you can see I have an UpdatableView in xml file with updatable_view id, but I can't select it via findViewById. The id somehow gets removed and I don't know why. I printed out the view hierarchy and this particular view doesn't have an id. the others have of course!
what can be the problem? I've tried cleaning, rebuilding, regenerating R. nothing helps!
UPDATE
in my activity's onCreate I do this
setContentView(R.layout.starter_activity);
ButterKnife.bind(this);
in UpdatableView class that extends FrameLayout I do this:
public UpdatableView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
inflate(context,R.layout.torob_updatable_layout,this);
ButterKnife.bind(this);
}
and torob_updatable_layout.xml is as simple as this:
<?xml version="1.0" encoding="utf-8"?>
<merge
xmlns:android="http://schemas.android.com/apk/res/android">
<com.rey.material.widget.ProgressView
android:id="#+id/progress"
android:visibility="gone"
android:layout_width="48dp"
android:layout_height="48dp"
style="#style/CircleProgressBar"
android:layout_gravity="center"
/>
<com.rey.material.widget.Button
android:id="#+id/retry"
style="#style/Button"
android:text="تلاش دوباره"
android:layout_gravity="center"
android:visibility="gone"
/>
</merge>
You have to use like below.
UpdatableView updateView = (UpdatableView)findViewById(R.id.updatable_view);
After hours of perplexity I found that one of my UpdatableView constructors was like this:
public UpdatableView(Context context, AttributeSet attrs) {
this(context, null, 0);
}
instead it should've been like this:
public UpdatableView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
Jesus! Make sure to pass the attrs or you won't get an id with your view.

Create custom layout in XML to initialize in code or in another layout xml

I have encountered an issue i am trying to resolve (or understand better the way it should be done) in creation of custom Layout in Android.
I want to create a custom RelativeLayout class for my use, which is defined in a layout XML file.
my_relative_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<com.mypackage.MyRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#null"
android:scaleType="fitStart"
android:src="#drawable/my_drawable"/>
<TextView
android:id="#+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/title_gray"
android:layout_below="#id/image_view"
android:gravity="center"
android:text="#string/placeholder" />
</com.mypackage.MyRelativeLayout>
Usage
public class MyRelativeLayout extends RelativeLayout {
private AttributeSet attrs;
private ImageView imageView;
private TextView textView;
public MyRelativeLayout(Context context) {
super(context);
}
public MyRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
this.attrs = attrs;
}
public MyRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.attrs = attrs;
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
if (attrs != null) {
TypedArray a = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.MyRelativeLayout, 0, 0);
drawableResource = a.getResourceId(R.styleable.MyRelativeLayout.image_view, 0);
a.recycle();
}
imageView = (ImageView) findViewById(R.id.image_view);
textView = (TextView) findViewById(R.id.text_view);
if (drawableResource != 0 && imageView != null) {
imageView.setImageResource(drawableResource);
}
}
}
My issue is that i want to initialise this layout both in another XML and in code.
But as I wrote my class and XML, i can only use it in code by doing:
myLayout = (MyRelativeLayout) LayoutInflater.from(this.getActivity()).inflate(R.layout.my_relative_layout, container, false);
When writing the following in another XML causes the onFinishInflate to fail on getViewById (returns null) and the childrenCount is 0
<com.mypackage.MyRelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="#id/another_layout"
app:image_view="#drawable/my_image" />
and doing the following, won't let me configure the custom image_view attribute.
<include layout="#layout/my_relative_layout"/>
To fix that, i can change the custom layout XML root element to be of type RelativeLayout and add the following to the beginning of onFinishInflate method:
LayoutInflater.from(getContext()).inflate(R.layout.my_relative_layout, this, true);
But the XML won't reference my class.
My questions are,
1. Am i missing something in the definition of the custom layout?
2. What is the correct definition for custom layout?
Thank you in advance!
First you should use the styled attributes in the contractor as shown in this example.
How can you expect from MyRelativeLayout that defined as fallow:
<com.mypackage.MyRelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="#id/another_layout"
app:image_view="#drawable/my_image" />
To be aware of views that are defined in my_relative_layout.xml?
To make it work you should create a costume layout and add it to com.mypackage.MyRelativeLayout manually.
Some thing like that:
costume_layout.xml
<?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="wrap_content">
<ImageView
android:id="#+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#null"
android:scaleType="fitStart"
android:src="#drawable/my_drawable"/>
<TextView
android:id="#+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/title_gray"
android:layout_below="#id/image_view"
android:gravity="center"
android:text="#string/placeholder" />
</RelativeLayout>
Your costume view
public class MyRelativeLayout extends RelativeLayout {
private AttributeSet attrs;
private ImageView imageView;
private TextView textView;
public MyRelativeLayout(Context context) {
super(context);
init();
}
public MyRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MyRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init(Context context){
LayoutInflater.from(context).inflate(R.layout.costume_layout, this);
}
}

custom ProgressBarPreference issue in Android

I'm trying to implement a custom ProgressBarPreference, adding at the bottom of a default preference a ProgressBar and a TextView, and granting the methods of the progressbar like setProgress() or setMax() for changing it. Here's my code works except the updating the progress within onCreate or onResume for example, how can I allow to set the progress in those points ? (actually is giving a null pointer exception over mProgressBar):
ProgressBarPreference.java
public class ProgressBarPreference extends Preference {
public ProgressBarPreference(Context context) {
super(context);
}
public ProgressBarPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ProgressBarPreference(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
}
ProgressBar mProgressBar;
#Override
protected View onCreateView(ViewGroup parent) {
LayoutInflater li = (LayoutInflater) Manager.appcontext.getSystemService(Service.LAYOUT_INFLATER_SERVICE);
View myLayout=li.inflate(R.layout.progressbarpreference, null, false);
((ViewGroup)myLayout.findViewById(R.id.preference_super_container)).addView(super.onCreateView(parent));
mProgressBar=(ProgressBar) myLayout.findViewById(R.id.preference_progress_bar);
return myLayout;
}
public void setProgress(int value){
mProgressBar.setProgress(value);
}
}
progressbarpreference.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout
android:id="#+id/preference_super_container"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:orientation="vertical"
></LinearLayout>
<RelativeLayout
android:id="#+id/relativeLayout1"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:paddingLeft="20sp"
android:paddingRight="20sp"
>
<TextView
android:layout_alignParentRight="true"
android:text="0 new of 100"
android:id="#+id/preference_progress_label"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:gravity="center"
android:layout_centerVertical="true"
android:paddingLeft="15sp"
android:textColor="#FFFFFF"
></TextView>
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/preference_progress_bar"
android:layout_centerVertical="true"
android:progress="50"
android:layout_toLeftOf="#id/preference_progress_label"
android:layout_alignParentLeft="true"
></ProgressBar>
</RelativeLayout>
</LinearLayout>
Ok have a solution (Android does it with an OnPreferenceChangeInternalListener but this is an easy working solution)
public class ProgressBarPreference extends Preference {
public ProgressBarPreference(Context context) {
super(context);
}
public ProgressBarPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ProgressBarPreference(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
}
private ProgressBar mProgressBar;
private TextView mLabel;
private int lastReqProgress=-1;
private int lastReqMax=-1;
private String lastLabel;
#Override
protected View onCreateView(ViewGroup parent) {
LayoutInflater li = (LayoutInflater) Manager.appcontext.getSystemService(Service.LAYOUT_INFLATER_SERVICE);
View myLayout=li.inflate(R.layout.progressbarpreference, null, false);
((ViewGroup)myLayout.findViewById(R.id.preference_super_container)).addView(super.onCreateView(parent));
mProgressBar=(ProgressBar) myLayout.findViewById(R.id.preference_progress_bar);
mLabel=(TextView) myLayout.findViewById(R.id.preference_progress_label);
if (lastReqProgress>-1){
mProgressBar.setProgress(lastReqProgress);
}
if (lastReqMax>-1){
mProgressBar.setMax(lastReqMax);
}
if (lastLabel!=null){
mLabel.setText(lastLabel);
}
return myLayout;
}
public void setProgress(int value){
if (mProgressBar!=null){
mProgressBar.setProgress(value);
} else {
lastReqProgress=value;
}
}
public void setMax(int value){
if (mProgressBar!=null){
int savedprogress=mProgressBar.getProgress();
mProgressBar.setMax(0);
mProgressBar.setMax(value);
mProgressBar.setProgress(savedprogress);
} else {
lastReqMax=value;
}
}
public void setLabel(String text){
if (lastLabel!=null){
mLabel.setText(text);
} else {
lastLabel=text;
}
}
}

Categories

Resources