I have library project that implements most of application functionality, it's like a template of application. Every project that uses this library can redefine some resources, themes and so on. Main case is colors and urls to get information, that this applicatoin would show. But to redefine some code is more problematic. For example there is view that displays information from xml, but xml is different and I need to parse it differently. My current realization is like this.
public class MyView extends LinearLayout {
public setData(XmlData xml) {
//call to helpers static method to get parsed data from xml
ArrayList<Item> items = ParseHelper.getItems(xml);
}
}
So what I need is only change some logic inside ParseHelper. Now I see only one way, to redefine layout.xml to change MyView to ProjectMyView in which I'll change method setData to use another ParseHelper. But it's not good.
Maybe there is some patterns or another ways to solve this?
I think another way to use different classes from library or project is to use reflaction. For example packages in project is differs only by name (com.library.helpers and com.project.helpers) and check for class in project, if exists use it, if no use from library. But I think it will use many resources.
Can anyone share their experience?
You can make MyView as abstract, and let setData as an unimplemented method and forcing all subclasses to implement this method like this:
public abstract class MyAbstractView extends LinearLayout {
public abstract setData(XmlData xml);
}
Them, you library has an class that extends MyAbstractView with the most usual implementation like this:
public class MyView extends MyAbstractView {
public setData(XmlData xml) {
//call to helpers static method to get parsed data from xml
ArrayList<Item> items = ParseHelper.getItems(xml);
}
}
For those which want a different implementation, they just need to also extend MyAbstractView.
Finally, the caller or these objects just need to do something like this:
public void init(MyAbstractView arg, XmlData xml) {
arg.setData(xml);
}
Related
Situation
I have a BaseActivity from which I extend other activities. In the BaseActivity I have a findCastedViewById which basicaly casts the view and then returns it.
I do this because I, personaly, find it ugly casting the view all the time.
Question
I was wondering if there is any problem or cons that I could get from using this approach that anybody else using this method had.
Here is BaseActivity:
BaseActivity.java
public class BaseActivity extends Activity{
//Other stuff
private <E extends View> E findCastedViewById(int id){
return (E) findViewById(id);
}
//Other stuff
}
Consider using ButterKnife, it solves the problem of having to continuously cast your views and it saves you a lot of time
Once you go butterknife, there's no way back
Basically you annotate the View variables with
#FindView annotation and it will find the correct view for you when ButterKnife.bind(this) is called
Here's a small snippet of code where ButterKnife is used from the GitHub Page
class ExampleActivity extends Activity {
#FindView(R.id.user) EditText username;
#FindView(R.id.pass) EditText password;
#OnClick(R.id.submit) void submit() {
// TODO call server...
}
#Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_activity);
ButterKnife.bind(this);
// TODO Use fields...
}
}
You can read more about ButterKnife from here
As lukaspp already noted, in SDK 26+ there is no need for vew casting.
They have implemented the same code as in the question, except it is now the default findViewById(). So yes OP, your code is good!
As explained in this answer, if you compileSdk is at least API 26, you don't need to cast the view anymore.
It's not only ugly but also an expensive operation if you repeat it constantly.
If you are sure you will always need that specific derived class, you can freely use it. However, I sometimes find I only need methods from the base class View, e.g. setVisibility(), in such occasions casting would be a waste.
This question already has answers here:
Extending from two classes
(13 answers)
Closed 9 years ago.
I want to extend two library class files in a java class.How to do this.
You have not given more details about the question.
You can only extend a single class. And implement interfaces from many sources.
Extending multiple classes is not available.
You can use nested classes or inner classes
class A extends B {
private class C extends D {
// A , B , C , D accessible here
}
}
Why Use Nested Classes?
Compelling reasons for using nested classes include the following:
It is a way of logically grouping classes that are only used in one place: If a class is useful to only one other class, then it is logical to embed it in that class and keep the two together. Nesting such "helper classes" makes their package more streamlined.
It increases encapsulation: Consider two top-level classes, A and B, where B needs access to members of A that would otherwise be declared private. By hiding class B within class A, A's members can be declared private and B can access them. In addition, B itself can be hidden from the outside world.
It can lead to more readable and maintainable code: Nesting small classes within top-level classes places the code closer to where it is used.
when to use nested classes
You can find more solutions on this link
Edit
This is an answer to you comment. You want to call method of outer class in inner class. This is an example.
class Outer {
void show() {
System.out.println("inside outter show");
}
class Inner{
void show() {
Outer.this.show(); //this is calling Outer class method into Inner class
Example e = new Example(); //create object of another class
e.show(); //call to method
System.out.println("inside inner show");
}
}
public static void main(String[] args) {
Outer o = new Outer();
Inner i = o.new Inner(); //create an object of Inner class
i.show(); //this is calling Inner class method from outside method
}
}
class Example
{
void show()
{
System.out.println("inside example show");
}
}
Output:
inside outter show
inside example show
inside inner show
Unfortunately in JAVA you can only extend a single class that means each Class can only extend one class. you can implement many interfaces but not extend.
however there are ways in which you can sort of surpass it, you can just make the libs public and then include them so you could create an instance and use their functions, you can create an inner class and use it for whatever purposes you need...
you can also create a chain of extension like:
public class A extends Activity
public class B extends A
so B will extend both...sort of
its hared to give you a working solution when we dont exactly know the issue,do you mean adding support libs? adding SDK? or really extending two classes (which is impossible straight forward).
#Aniket gave you an example of how to work around it so to speak...
hope I helped
sorry for the bad news:)
I'm implementing AdapterView<ListAdapter> to produce an AbsListView-like class I can use with a CursorAdapter in a layout. I'm implementing this because I want to use the handy automatic data update behaviour CursorAdapter gives you; additionally, I can reuse the same adapter in a more conventional ListView elsewhere in my app.
I'm basing my class heavily on the Android source for AbsListView.
I'm having trouble with this though: in my own class, also extending AdapterView<ListAdapter>, I put this code:
class AdapterDataSetObserver extends AdapterView<ListAdapter>.AdapterDataSetObserver {
#Override
public void onChanged() {
super.onChanged();
//my update code here
}
#Override
public void onInvalidated() {
super.onInvalidated();
//my shutdown code here
}
}
Eclipse says "AdapterView.AdapterDataSetObserver cannot be resolved to a type".
I can't see that this is controlled by an import, and clearly since ListView can override this class, I would expect to be able to as well. Why isn't it visible?
The AdapterView.AdapterDataSetObserver is package private according to the javadoc. See the link here: http://www.androidjavadoc.com/1.0_r1_src/android/widget/AdapterView.html .
Thus it will not be visible outside of the package.
I am trying to create a compound component in android. This compound component have 2 inner components. one of them is a custom component (assume CompX ) with some public methods.
And the second component is the plain button
So the compound component looks like the below,
class CompoundComp extends LinearLayout{
private CompX customComp;
private Button comp2;
public void method1(){
------------------------------
------------------------------
}
-----------------------
-----------------------
}
class CompX{
public void methodA(){
----------------------
}
public void methodB(){
----------------------
}
}
Now I am using the Compound Component from a client program as,
class Client{
CompoundComp compoundObj = new CompoundComp();
compoundobj.method1();
}
Now my problem is to access the CompX methods. My known solutions for this are as,
In CompoundComp class create public methods that in turn calls the CompX public methods
Make CompX instance as public in CompoundComp class so that the client can call them directly
Frankly I am not able decide which way to go as I am unable to conclude on the pros 'n' cons of both the solutions.
Someone please suggest me if my solutions are proper one or not. If so which one is the better one to use, if not so please give me some suggestions or clues of solutions.
Thanks
The CompX class is not static, so you can't create a instance of it.
To initialize a inner non-static class you should create it with a object of the outer class.
I have a rather large amount of code written when I decided to use
ORMLite.
After reading the doc I found that I would need to extend like:
MyClass extends OrmLiteBaseActivity<DatabaseHelper>
but I have already extended it with ListActivity.
Is is possible to do it without extending OrmLiteBaseActivity?
Tnx in advance.
It is not a requirement to extend OrmLiteBaseActivity. You'll just need to manage more of the utility functions yourself.
Your best option would be to create your own DatabaseHelper inside your activity and to manage how many users there are of it and to discard it when it is done being used. Generally speaking, this is the utility that the OrmLiteBaseActivity gives to you. A mechanism which will manage your database objects for you. It's just a convenience.
Example:
private static Dao<Agent, Object> agentDao = null;
public void someMethod() {
if(agentDao == null){
helper = (MyDBHelper) OpenHelperManager.getHelper(getContext());
try {
agentDao = helper.getAgentDao();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
I had implemented a method to return my DAOs on the class MyDBHelper. Take a look at the ORMLite Android Javadoc as well as the more general ORMLite Core Javadoc. There are lots of good examples out there.
[ #Nick's answer is fine but I thought I'd add more information. ]
ORMLite is missing a OrmLiteBaseListActivity class that was added in version 4.10 -- sorry about the miss. In the meantime, you can easily create your own version of this class by copying the OrmLiteBaseTabActivity class changing the class that it extends from TabActivity to ListActivity. Then change all of your list activity classes to extend this new class. Once 4.10 is out then you can go back and remove the class.
For example:
public abstract class OrmLiteBaseListActivity<H extends OrmLiteSqliteOpenHelper>
extends ListActivity {
// insert contents of the OrmLiteBaseTabActivity class here
}