I know this is probably a very simple answer, but I'm a little stumped here. I'm creating a custom view, Panel, with the following constructor:
public Panel(Context context, AttributeSet attrs, int barLength){
super(context, attrs);
//paint object for drawing in onDraw
barPaint = new Paint();
bar = new Rect(3, 13, barLength, 3); // Rect object
//...other stuff, etc etc
}
In the activity where this view will be used, it will be created five different times within different cells of a table layout. Panel is a really simple Rect whose length will vary based on the argument barLength.
So, in the activity where the Panel views are actually created, they're called like so:
private Panel tagBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tagBar = (Panel) findViewById(R.id.custView);
}
As you can tell, this doesn't use the constructor I outlined above. How do I instantiate a new Panel, including properly passing it the right Context and AttributeSet? It seems now that when constructed (without int barLength as an argument) those just get passed in automatically. How should the tagBar be instantiated to properly pass it all three arguments?
To clarify, attrs.xml is a styleable attributes file that is mainly used to help set the colors of the bars from xml. Can anyone give me any direction?
Thanks!
If you have the panel class in the xml, the framework calls the proper constructor for you, passing it the Context and Attributes. You can then create a new attribute in attrs.xml, and once that's done you can pass the bar length via xml as well
<resources>
<declare-styleable name="Panel">
<attr name="barLength" format="int" />
</declare-styleable>
</resources>
Then in the xml just add barLength=n, just like you would any other attribute in the xml, but without android: in front of it.
Related
How can I passs multiple strings into custom views constructor in android
public DrawSomethingView(Context context, String originalBgPath, String pattern) {}
and why it forces to do it like that ?
public DrawSomethingView(Context context, AttributeSet S){
You need the standard constructors so the framework knows how to inflate them, e.g. from an XML layout. If you put a DrawSomethingView in your layout, how would it know what to pass for originalBgPath etc? You also need a Context and AttributeSet at a minimum to call one of the View superclass's constructors. You can read more about it here
That link also tells you how to create your own attributes, that you can add to the XML for your custom view, and pull out the data in the class itself. So you could add your strings as part of the XML definition. If you want to set them programmatically instead, you'll need to add some properties you can set (which you could also set when you read those attributes).
But there's no way to force them to be set, since you can't create your own version of the constructor that requires them (and the framework wouldn't have values to provide anyway). So you'll need to handle the possibility they're missing (e.g. nullable properties, default values), and maybe write a builder function that you can call from your code, that does require those values and creates and sets up the custom view before passing it back to you.
I've referred RangeSeekBar to implement Seekbar with two thumbs.
I'm getting following error in log:
Caused by: java.lang.NoSuchMethodException: RangeSeekBar(Context,AttributeSet)
and if I try to add following method in RangeSeekBar.java, I'm getting error as : The blank final field numberType may not have been initialized
public RangeSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
I'm banging my head from few hours, but haven't find any fruitful solution.
Any help appreciated.Any other way to implement SeekBar With Two thumb is also welcome.
Any custom view in android should have a constructor like you wrote. So, keep it. The problem is, you have a final field in your class, that should be initialized in constructor. So, remove final modifier from that variable, or set it to some value in constructor.
About RangeSeekBar:
this class is using generic types for detecting what type of number you want to use (float, double, or just int values). So, do not put this as a view in xml layout file, and add it in code like this:
someViewGroup.addView(new RangeSeekBar<Integer>(0, 10, context));
which someViewGroup is the view you want to put RangeSeekBar in it. (its parent).
Any one please guide me,
How to create a custom component in xml and java file
pass attributes from xml (this i somewhat completed)
how to pass attributes dynamically from new customClass() -- constructor method. -- i dont know how to implement this point
for Eg : I created a custom component with two textview as a single component. In xml i created two component by xml attributes. Now i want to create two new component by java code
by calling the constructor of my customClass.java I dont know how to create a new component dynamically from java code and how to display that in a view(Say a relative layout) Please help me provide any link or blog.
I have spent 1 week for this, But i didnt get any solution please help me
its very simple:
in your layout xml file simply put the following lines of xml code:
<com.example.project.MyComponent
android:id="#+id/myid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
Now, write a class named as your component:
public class MyComponent extends RelativeLayout {
public MyComponent(Context context, AttributeSet attr) {
super(context,attr);
}
#Override
public void onFinishInflate() {
// this is the right point to do some things with View objects,
// as example childs of THIS View object
}
}
Remember the constructor: this constructor is needed by the LayoutInflater to
find your component. And, dont forget to call super(...) when required.
You can do this by calling the constructor with context in its parameter and then setting the attributes with getter setters. You can find a good tutorial at Android tech point
MyComponent mycomponent = new MyComponent(context);
myComponent.setFirstTextView("text1");
myComponent.setSecondTextView("text2");
And then finally
layout.addView(myComponent);
android newbie here.
My first game involves a custom view, which is going to draw a game board and some scoreboards on the screen. I need to know how many players there are in order to get the number of scoreboards up, and I need this to be in known in the constructor of the custom view, so that appropriate variables are initialised on time.
My current implementation is like this, is this the correct way to get variables into the custom view constructor?...
I instantiate the custom view from my activity like this:
numPlayers=2;
setContentView(R.layout.gamescreen);
mBoardView = (BoardView) findViewById(R.id.board_view);
And in the custom view constructor:
public BoardView(Context context, AttributeSet attrs){
super(context, attrs);
vNumPlayers = ((GuappsXOMainGame)getContext()).getNumP();
That's how I have it now and it seems to work well enough, but is it better to be doing something along the lines of the answer to this question:?
android:how to instantiate my custom view with attributeset constructor
When a custom view (or SurfaceView) is the only view, often in games, then it is very easy to pass parameters like level, players, sound on etc by creating an instance of this view before setContentView(). An example:
MyView myView = new MyView(level, players, soundOn);
setContentView(myView);
In your case, your custom view is instantiated when the layout is created, hence you have to communicate back to the activity object to get the values. This is also possible. I have done this by setting static variables in the activity before calling setContentView(my_layout) then in the constructor for the custom view just say level = MyActivity.level
Or perhaps the way you are doing already where you obtain the instance of the activity and call a public method or variable.
In the link you provided an attribute is "hard-wired" into the XML layout. I don't see the advantage of that, when one can simply enter the value into the custom view class itself as a "final" variable.
I am new to android .can any one solve the following problem?
I just create the class like below .I need to know how to set property for the Edit text field
public class CustomEditText extends EditText{
public CustomEditText(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
}
Note: I mean the property like this
Edittext.setText("Demo");
Thanks in advance.
You need to create member variable and methods inside your CustomEditText.
Once you have them you can access it.
So there are a couple ways this can be interpreted and I will try to cover all of them.
EditText has multiple constructors. The one you have overridden requires that you as the developer set the properties in code for the rest of this instances usage. So you can actually just call setText(someString) from within this class or since the method is public call it directly on an instance of your class.
If you override the constructor that contains an attributeSet,
EditText(Context, AttributeSet)
You can use your component as part of an xml layout and set attributes on it there as if it were another EditText (as long as you call super(context, attributeSet). If you want to define your own custom attributes on top of that then that's actually quite neat how you do this.
In your project hierarchy, from the root you should either have or need to create a folder called "res/values" Within that folder a file named attr.xml should be created.
<declare-styleable name="myCustomComponents">
<!-- Our Custom variable, optionally we can specify that it is of integer type -->
<attr name="myCustomAttribute" format="integer"/>
...
<!-- as many as you want -->
</declare-styleable>
Now within your new constructor that makes use of the AttributeSet, you can read this new attribute, "myCustomAttribute".
public CustomEditText(Context context, AttributeSet set) {
super(context, set);
// This parses the attributeSet and filters out to the stuff we care about
TypedArray typedArray = context.obtainStyledAttributes(R.stylable.myCustomComponents);
// Now we read let's say an int into our custom member variable.
int attr = typedArray.getInt(R.styleable.myCustomComponents_myCustomAttribute, 0);
// Make a public mutator so that others can set this attribute programatically
setCustomAttribute(attr);
// Remember to recycle the TypedArray (saved memory)
typedArray.recycle();
}
Now that we have declared our new attribute and have setup code to read it, we can actually use it programatically or in an XML layout. So let's say you have an Xml layout in file, layout.xml
<ViewGroup
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res/com.my.apk.package"
>
...
<com.my.full.apk.package.CustomEditText
android:id="#+id/custom_edit"
...
custom:myCustomAttribute="12"
/>
...
</ViewGroup>
So in this we create a layout like normal, but notice we declare a new xml namespace. This is for your new component and your apk. So in this case "custom" is being used it will look inside your defined stylables for new parameters. By doing the previous steps with attr.xml, you have declared "myCustomAttribute" as a component attribute off of the http://schemas.android.com/apk/res/com.my.apk.package namespace. After that it's up to you to decide what attributes you would like to expose and what those attributes actually mean. Hope that helps.