I'm currently writing a plugin that is attempting to add a view to the current LinearLayout of my application.
Though I am struggling to get access to the linear layout from within a plugin, I can add the view fine if I do so within my main activity as so:
MyView view = new MyView(this);
root.addView(myView);
But to get the root LinearLayout in my plugin I have assumed that:
this.cordova.getActivity();
is my main activity and have been trying to cast it to the type of my main activity and call a function I added that will return the root LinearLayout object as so:
MyActivity myAct = (MyActivity)this.cordova.getActivity();
MyView view = new MyView(myAct);
myAct .GetLinearLayout().addView(view);
Though this doesn't seem to work and I receive no errors or such to help figure out why?
Anyone know how I can get access to the layout to add my view?
Okay so I solved this slightly differently to what I was attempting to do above.
Firstly casting the activity returned by cordova:
MyActivity myAct = (MyActivity)this.cordova.getActivity();
Does actually work and returns the instance of your main activity, so that wasn't the problem.
In the end I couldn't figure out why adding another view to the root cordova layout from the main activity worked but not when I did so in a plugin so what I did was to create my view from within the activities onCreate() then I provided an accessor to the view class back to my plugin and worked on from there.
The layout no longer exists after init() completes. The last thing that happens in init() is setContentView() is called with the layout. When setContentView() is called with a layout, the layout is inflated and the individual views in the layout are added to the activity.
Related
My question is about Android/Java.
How can I call my custom view with a name such as
<input>
instead of
<org.javaforum.input>
without adding anything in the MainActivity.java?
I already read this: https://stackoverflow.com/a/17478278/16627950
But there I must add something in MainActivity.java.
I also read this: https://stackoverflow.com/a/30066376/16627950
But I don't know where do the variables mInflator and mPrefix come from.
I also read this: https://stackoverflow.com/a/13316335/16627950
But I don't know what are the programmatically steps to do so.
So how can I hook into the layout inflation in code, and handle instantiating my class for that tag myself?
mInflator and mPrefix, are custom properties declared at the top of the activity class, nothing special, in order to implement the custom layout you have to call:
val myInflater = LayoutInflater.from(this)
.cloneInContext(this)
myInflater.factory2 = MyLayoutInflater()
This from your onCreate method of the activity, I think that is not possible to add a factory without tounching the activity code
I'm working on a "home feed"-like feature where there's a main Fragment with several other fragments added to its layout, making up the content page. I'd like the main fragment class to be able to instanstiate all the fragment classes that inherit from a certain parent fragment class. This way the code would be more dynamic instead of adding a bunch of <fragment> tags to my xml files.
I'm kinda stuck on making up a decent architecture. How would you go on about doing this?
UPDATE:
Here's what I'm basically trying to do, but don't know how:
public class FeedFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View parentView = inflater.inflate(R.layout.fragment_home, container, false);
// Get fragments and dynamically add them to
// the FeedFragment's layout
getEntryFragmentsList();
// ...
return parentView;
}
}
public abstract class FeedEntryFragment extends Fragment {
// Somehow add fragment to list of entry fragments
}
public class TestFragment extends FeedEntryFragment {
// Already added to list of entry fragments
}
I don't think that possible to decrease the count of xmls by inheritance. I think you should try to split your xml configurations and use some <merge> or <include> to build the full one from the parts.
May be I can provide more help if you will describe your problem in more details.
You should use FrameLayout to add fragment(s) dynamically by using the FragmentTransaction.
You can also use a ViewPager with tabs or bottom tabs to show multiple fragments. Please check sample from my Dynamic Support library for the complete code.
Abstract fragments
DynamicFragment - Abstract base fragment from the Dynamic support library.
DynamicViewPagerFragment - Abstract fragment which extends the DynamicFragment to implement the ViewPager functionality.
Implementation
HomeFragment - Sample fragment extends the DynamicFragment to implement the home screen.
SettingsFragment - Sample fragment extends the DynamicViewPagerFragment to implement the settings functionality using multiple fragments inside a view pager.
Tutorial Implementation
This better suits your need. TutorialActivity returns a list of fragments to be displayed inside a ViewPager.
DynamicSimpleTutorial generates a DynamicTutorialFragment according to the supplied parameters.
I'm having some issues starting an activity in an Activity class that is called by a Fragment class (technically a PageAdapter inner class... the Android tab example is odd).
One of the tabs contains a list and I'd like to start a new activity when an item is clicked. I currently have a separate activity class which handles the list and interactions.
I've tried quite a few things such as getting the activity in the fragment and passing through the constructor. As well I have tried just about everything mentioned in this stackoverflow thread with no avail.
Currently in the PageAdapter (Non essential code omitted)
public Object instantiateItem(ViewGroup container, int position) {
.
.
View view;
.
case 1:
view = getActivity().getLayoutInflater().inflate(R.layout.forum,
container, false);
lva = new ListViewActivity(view);
break;
This is to create a new a instance of the activity which will populate the view and listen for clicks. From this class I'd like to startActivity() with a new intent. Any thoughts would be much appreciated!
I have three activities in my app
A login activity
A main activity
A detail activity
I want to use espresso to test a sequence of events: click the login button on the login activity, which opens the main activity, and then click a list item in main activity, which opens detail activity, and then click another button in the detail activity. I started by creating this simple test, to get a reference to the listview:
public class LoginActivityTest extends ActivityInstrumentationTestCase2<LoginActivity> {
public LoginActivityTest() {
super(LoginActivity.class);
}
#Override
public void setUp() throws Exception {
super.setUp();
getActivity();
}
public void testSequence() throws Exception {
// Login
onView(withId(R.id.button_log_in)).perform(click());
// Check if MainActivity is loaded
onView(withId(R.id.container)).check(matches(isDisplayed()));
// Check if Fragment is loaded
onView(withId(R.id.list)).check(matches(isDisplayed()));
}
}
On the mainActivity onCreate() method I load a fragment like this:
getFragmentManager().beginTransaction()
.add(R.id.container, mListFragment)
.commit();
The ListFragment fragment has a list (R.id.list), but still the test fails with a NoMatchingViewException:
android.support.test.espresso.NoMatchingViewException: No views in hierarchy found matching: with id: com.tests.android.development:id/list
What am I doing wrong?
A note from the documentation for onView:
Note: the view has to be part of the view hierarchy. This may not be
the case if it is rendered as part of an AdapterView (e.g. ListView).
If this is the case, use Espresso.onData to load the view first.
To use onData to load the view, you need to check for instances of whatever your adapter is in the ListView. In other words, if your listview uses a Cursor adapter, you can try this:
onData(allOf(is(instanceOf(Cursor.class)))).check(matches(isDisplayed()));
It is important to note that the above will only pass if your listview contains at least one item. It is a good idea to have one test where an item exists, and one test where an item does not.
For more information on how to check for data that does exist, see here.
For more information on how to check for data that does not exist in an adapter, see here.
In the current version (Espresso 2.2.2) this exception is always appended with a View Hierarchy: clause that lists all the views available to match. Stroll through that and check if you can find your list.
As an alternative: check out android-sdk\tools\uiautomatorviewer.bat (or .sh) which takes a snapshot from the current screen and hierarchy. Put a breakpoint on your list matching line and check with the viewer if the list is there. If you find the list, there may be a timing issue in the test. Maybe it didn't wait enough, check out more about IdlingResources.
When developing for the android. Are we bound to using xml layout files? (In res\layout )
Or can we skip them entirely and programmatically create and implement our layouts for UI?
Sure you can.
In an Activity you can use setContentView(View view) instead of setContentView(int resource) in the onCreate() callback.
If you use a Fragment you can programmatically create a View instead of inflating a resource. This has to be done in the onCreateView() callback of the fragment