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
Related
I am building a video playing app in Java where I use three Fragments. In one of them I have a list of videos to be played (using a simple ListView widget) where I use a Custom Adapter to pass the titles and the bitmaps thumbnails/uri paths of those videos. When I use Glide to generate and show the bitmaps in the ImageView section of the Custom Adapter, it works (passing only uri paths from Fragment), because the context in the getView() function works as well.
But I want to generate the bitmap thumbnails using Glide in the ListView Fragment, not in the Custom Adapter class, because I need those thumbnails in other Fragments of the app. Unfortunately I didn't managed to create the thumbnails in the ListView Fragment, because the context I am writing at Glide.with() in the onCreateView() function doesn't work!
What is the proper context to be used for Glide in the ListView Fragment to see it and generate the bitmap thumbnails?
I used this code in the ListView Fragment:
Glide.with(this)
.asBitmap().load(uri)
.into(new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(#NonNull Bitmap resource, #Nullable Transition<? super Bitmap> transition) {
bitmapThumbnail = resource;
}
});
but it doesn't generate any thumbnails.. :((
In your Fragment you can get the parent Activity Context by calling getContext()
I just found out that the problem wasn't the context I added to Glide.with() section, but the fact that the bitmap generated inside the "onResourceReady(...)" method stays in there and it cannot be used outside the method, only inside and as an argument for an "imageView.setImageBitmap()" method...
As I understood by now, Glide only intermediates between the url/uri/path and the imageView widget, it's not generating any bitmaps outside itself! This is a valuable thing I learned about Glide!
Many thanks for all the help I received!
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 have a class that is handling a database in my Android app. When the database changes, I'd like to update the fragment displaying the information from the frogment. My approach has been to give the fragment a tag and then find the fragment with the following code:
FragmentManager manager = getFragmentManager();
Fragment fragment = manager.findFragmentByTag("Schedule");
if (fragment instanceof ScheduleFragment){
ScheduleFragment fr = (ScheduleFragment)fragment;
fr.scheduleUpdated();
}
However, as long as my database class is not an extension of Fragment, the compiler refuses to recognise getFragmentManager(). To me it makes no sense to extend Fragment, as the database class is no fragment, but a simple helper class to manage the database. Is it possible to get a reference to my fragment without extending Fragment? Or is this bad practice and should be done in another way?
Also, is it possible to get a reference to the fragment from a static method?
try using a localBroadcast manager. when database changes laumch a Broadcast intent. registere this in "Schedule" Fragment and you can handle the database changes.
Refer to this link for more about LocalBroadcast Manager
how to use LocalBroadcastManager?
http://www.vogella.com/tutorials/AndroidBroadcastReceiver/article.html
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.