2

I inherit all of my activities and fragments from base activity and base fragment.

I want to centralize some behaviors across applications and create some separate git repositories for them.

A convention is that each activity and fragment should have a main ProgressBar that is embedded inside XML layout anywhere, and its id is simply progress.

The problem is that the ProgressBar class is defined in another git repository, while the actual XML is defined in other git repositories. Thus I have no access to R.id.progress in my code.

In my BaseActivity I have this code:

public class BaseActivity extends AppCompatActivity {

    ProgressBar progress;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        try {
            progress = findViewById(R.id.progress); // this line is red
        } catch (Exception ex) {
            // notifying error
        }
    }

    public void showProgress() {
        // showing progress
    }

    public void hideProgress() {
        // hiding
    }
}

So that in all of my activities I simply call showProgress(); whenever I need to.

How should I solve this problem?

Angel Koh
  • 12,479
  • 7
  • 64
  • 91
  • Have you included that other project in your project? – Reaz Murshed May 10 '18 at 13:27
  • simply extend your baseactivity to other activities –  May 10 '18 at 13:30
  • @ReazMurshed, I'm referencing the `framework` project from `app1`, `app2`, etc. It's not the other way around. The problem is that my `framework` is not built stand-alone.` – mohammad rostami siahgeli May 10 '18 at 13:31
  • Possible duplicate of [android how to create my own Activity and extend it?](https://stackoverflow.com/questions/8821240/android-how-to-create-my-own-activity-and-extend-it) –  May 10 '18 at 13:33
  • 2
    @Selvin, not helpful at all. – mohammad rostami siahgeli May 10 '18 at 13:38
  • check resource types in official documentation – Selvin May 10 '18 at 13:39
  • What's the package you have imported for `R`? – nabs.boro May 10 '18 at 13:49
  • Is `R`'s package is main app's package or framework's package? – nabs.boro May 10 '18 at 14:03
  • can you update the question to show the relationship between all the git repositories and your app? are they separate projects/modules or libraries? If I am reading you correctly, you want to re-use common xml that you have packaged into a separate module and added to your project? – Angel Koh May 10 '18 at 14:06
  • I'm not certain, but I suspect you can't (at least, through any standard path) do this - resources for each app / library are kept separated from each other so that they don't conflict. It's probably *possible* to just use the ID, but hacky. I would recommend creating a XML element to hold the view, and the load it programmatically in your code into that view. If someone else knows how to do this, I'm curious how. – Bassinator May 10 '18 at 14:19

2 Answers2

2

If your BaseActivity is reside inside a base module (let's call BaseActivity Module) and the actual activity and xml is inside another module (let's call Activity Module) which is depends on BaseActivity module like this hierarchy:

 Activity Module
   -- BaseActivity module

Then you can create an xml file which contains R.id.progress in BaseActivity as a temporary id.

When you're using create a subclass from BaseActivity where the subclass activity has an xml containing R.id.progress. Your activity will use the R.id.progress from the xml instead from BaseActivity.

Please be noted that each xml with some specific name can be override by adding xml with the same name. For example, if you have view_progress.xml in BaseActivity module, it will be overridden by the view_progress.xml in Activity Module.

ישו אוהב אותך
  • 28,609
  • 11
  • 78
  • 96
1

As long as you have that id in one of the layout files the ID will be generated inside the R file. Still probably a better idea to use an abstract class and method which then specify the id in subclasses:

abstract int getProgressBarId();

so then you can do this:

@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        try {
            int progressBarId = getProgressBarId();
            if(progressBarId != 0) {
                 progress = findViewById(R.id.progress);
            } 
        } catch (Exception ex) {
            // notifying error
        }
    }
breakline
  • 5,776
  • 8
  • 45
  • 84
  • Layout files are in another project. The `BaseActivity` has no idea about the real `ProgressBar`. It just knows it has to be there by convention. And I don't want to implement that abstract method throughout my all activities. It's convention over configuration. – mohammad rostami siahgeli May 10 '18 at 13:52
  • My other suggestion would be to look into Databinding. Then you dont need to use findViewById at all. Simply use an ObervableBoolean in your layout file and update the visibility of the Progressbar there. A much cleaner and modern approach. – breakline May 10 '18 at 15:27