Can someone please explain the real difference between ImageView and com.facebook.drawee.view.SimpleDraweeView.and why fresco not use imageview.?
can we upload a image on server through fresco? if yes please share code..
Unlike Codo's answer that discusses the "deeper" difference between these classes (see The Image Pipeline section here), I'll discuss the usability difference.
Going over the source code of SimpleDraweeView and related classes one can see the following inheritance hierarchy:
public class SimpleDraweeView extends GenericDraweeView
public class GenericDraweeView extends DraweeView<GenericDraweeHierarchy>
public class DraweeView<DH extends DraweeHierarchy> extends ImageView
The following description appears before the class definition of DraweeView:
Although ImageView is subclassed instead of subclassing View directly, this class does not support ImageView's setImageXxx, setScaleType and similar methods. Extending ImageView is a short term solution in order to inherit some of its implementation (padding calculations, etc.).
This class is likely to be converted to extend View directly in the future, so avoid using ImageView's methods and properties (T5856175).
So we know that DraweeView presently inherits from ImageView - which usually means that "it does everything ImageView does and more" (with the exceptions discussed in the comment block above). This simplistic approach can give you a general idea but ignores the most important aspect of compatibility with Fresco.
The Fresco docs explain how to use drawees, and you can see right from their XML definition that they are much more customizable than ImageView:
<com.facebook.drawee.view.SimpleDraweeView
android:id="#+id/my_image_view"
android:layout_width="20dp"
android:layout_height="20dp"
fresco:fadeDuration="300"
fresco:actualImageScaleType="focusCrop"
fresco:placeholderImage="#color/wait_color"
fresco:placeholderImageScaleType="fitCenter"
fresco:failureImage="#drawable/error"
fresco:failureImageScaleType="centerInside"
fresco:retryImage="#drawable/retrying"
fresco:retryImageScaleType="centerCrop"
fresco:progressBarImage="#drawable/progress_bar"
fresco:progressBarImageScaleType="centerInside"
fresco:progressBarAutoRotateInterval="1000"
fresco:backgroundImage="#color/blue"
fresco:overlayImage="#drawable/watermark"
fresco:pressedStateOverlayImage="#color/red"
fresco:roundAsCircle="false"
fresco:roundedCornerRadius="1dp"
fresco:roundTopLeft="true"
fresco:roundTopRight="false"
fresco:roundBottomLeft="false"
fresco:roundBottomRight="true"
fresco:roundWithOverlayColor="#color/corner_color"
fresco:roundingBorderWidth="2dp"
fresco:roundingBorderColor="#color/border_color"
/>
As for uploads - it seems like Fresco is only intended for downloading images. You might want to look into Robospice/Retrofit for your uploading needs.
Android versions before Android 5 have serious problems with handling a large number of images. Android 2 has problems if they are on the Java heap and Android 4 doesn't properly release them if you don't destroy the activity.
So Fresco moves images to the native heap (Android 2) and implements its own reference counting for Android 4 in order to know when the image is no longer reference and can be recycled.
They replace ImageView with SimpleDrawView in order to have full control about the references to the images. In fact, only there low level API gives you direct access to the image at all. Otherwise their approach with reference counting would work.
The facebook provides its own ImageView, So rather than creating your own CustomView or ImageView you can use their View.
But, Remember you could have a less control on it as compared with your own Custom View.
This gives you a complete package and Functionality for a Button, View or Anything like that.
Like this here for Rounded Corners of a ImageView
<de.hdodenhof.circleimageview.CircleImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:id="#+id/userImage"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp" />
Related
I'm using a leanback BrowseFragment to implement a simple android tv app. I have two PageRows which are backed by custom fragments. When I switch between the two in the browse navigation area, the content side of the screen goes blank briefly before the new fragment's views appear. How can I fade from one view to the other without a delay in between?
I see some references to "entrance transition" in the docs which I think is what I need, but I can't find any examples of what to do in those callbacks.
https://developer.android.com/reference/android/support/v17/leanback/app/BrowseFragment.MainFragmentAdapter.html#setEntranceTransitionState(boolean)
I tried to implement setEntranceTransitionState on my PageRow Fragment's MainFragmentAdapter, but it is never invoked:
class GuideFragment: Fragment(), BrowseFragment.MainFragmentAdapterProvider {
val fragmentAdapter = object: BrowseFragment.MainFragmentAdapter<GuideFragment>(this) {
override fun setEntranceTransitionState(state: Boolean) {
Log.v("TEST", "setEntrance($state)")
fragment.setEntranceTransitionState(state)
}
}
override fun getMainFragmentAdapter() = fragmentAdapter
}
There is no way to do this when using BrowseSupportFragment.
If you look at the implementation of swapToMainFragment(), you'll see that while scrolling the content is set to an empty fragment. When SCROLL_STATE_IDLE is reached, a regular fragment transaction is used to replace the child fragment with the new content.
leanback has a lot of limitations, It is better to fork the official code and create your own repo and modify it; we did the same in our app.
In PrismForms we got the problem, that the NavigationStack is empty after navigating to a new page. That means after using the hardware back-button on the SecondPage, the app is closed. Although the back-arrow in the header on Android isnt shown. If looking closely you can see the back-arrow for a short moment after the page is switched. I guess thats before the NavigationStack gets cleared.
To the first page we navigate with the following command in OnInitialized() in our App.xaml.cs which derives from PrismApplication.
NavigationService.NavigateAsync("NavigationPage/StartPage");
(If only Navigating to „StartPage“ here, the Stack doesnt get cleared.)
That has do to with PageNavigationService.ProcessNavigationForNavigationPage(...) calling
bool clearNavStack = GetClearNavigationPageNavigationStack(currentPage); and PageNavigationService.ProcessNavigationForContentPage(...) not.
From the StartPage to the next we navigate with NavigateAsync("SecondPage")“. Here the described behaviour appears.
For navigation we use a class which wraps the Prism NavigationService. We hold him as a property and get him via Unity in our constructor:
this.PrismNavigation = prismNavigation ?? throw new ArgumentNullException(nameof(prismNavigation));
The methods „NavigateAsync“ and „GoBackAsync“, etc. we just pass through.
This way we want to seperate our ViewModel-Project from references to XamarinForms to later be able to use the same ViewModels for for example a WPF-GUI.
Why is the stack beeing cleared by our own NavigationService? If we register the original Prism NavigationService in App.xaml.cs instead, navigating back works as expected again. We found the point in the framework and could avoid the clearing with a drity hack, but that’s against the navigation-logic implemented in PrismForms, but we don’t understand how to do it the correct way.
Every help appreciated!
We edited a few things to get it working after finding some interesting information by Brian Lagunas in the forlast-post here:
https://github.com/PrismLibrary/Prism/issues/591
Although the topic was about something else, it led to improvements for overwriting the Navigation Service.
Remember that in your viewModels the Navigation Service must be named "navigationService" by convention. Also we switched from just holding the Prism Navigation Service as a parameter to deriving from it as suggested in the link above.
public class MyNavigationService : UnityPageNavigationService
As I understand it, when using FXML to describe a Java FX scene, the controller class is written manually and it's member variables and methods can then be referenced from the .fxml file. When loading the scene using the FXMLLoader, member variables are set to the corresponding scene elements and methods are wired up to the corresponding events automatically. This works but is very cumbersome as changes need to be done in two places and any mistakes will only show up at runtime.
I've seen other GUI frameworks that allow you to instead generate the controller from a scene description as an abstract class which needs to be implemented to access the scene elements and handle the events. An example of what I mean:
I would create the following .fxml file (e.g. using the JavaFX Scene Builder):
<AnchorPane ... >
<children>
<Button fx:id="button" ... text="Button" onAction="#buttonPressed" />
</children>
</AnchorPane>
Somewhere in my build process, the following .java file would be created (e.g. using a Maven plugin):
abstract class TestController {
protected final Parent root;
protected final Button button;
{
// Load test.fxml file
// Assign scene elements to root and button
// Attach event handler to the button that calls buttonClicked()
}
protected abstract void buttonClicked(ActionEvent event);
}
I could then, possibly multiple times, create a concrete implementation of that controller:
final class TestControllerImpl extends TestController {
TestControllerImpl(String buttonLabel) {
button.setText(buttonLabel);
}
#Override
protected void buttonClicked(ActionEvent event) {
button.setText("I've been clicked! What a great day!");
}
}
Is there a project with the goal to do this? Or is there a problem with this approach applied to FXML?
I see the following benefits from this approach:
Declarations for member variables and methods for the controller are automatically generated.
All member variables are final and protected instead of non-final and either public or annotated.
The same for methods, they are protected instead of either public or annotated.
Not implementing a method or misspelling it's name will lead to a compiler error.
Programmatic setup of the scene can be done in the constructor instead of an initialize() method because the constructor will run after the scene has been loaded and its elements assigned to the member variables.
This is now supported in SceneBuilder, NetBeans and in Eclipse. Note this works out of the box in NetBeans and SceneBuilder, but in Eclipse you first need the e(fx)clipse plugin.
SceneBuilder:
With an FXML file open in the editor, enter the menu to select "View" and "Show Sample Controller Skeleton".
Eclipse:
Open the fxml file so the contents are displayed in the code editing pane (you should see the fxml as plaintext xml with syntax highlighting inside Eclipse, not rendered visually in SceneBuilder). Right-click on the code in Eclipse and select "Code" and then "Generate Controller".
NetBeans:
In NetBeans it is even easier, right-click the fxml file in the project explorer and select "Make Controller".
Update Nov 2020
This answer is now outdated.
As various more recent answers have pointed out, there are now a variety of additional different tools available for automatically generating FXML controller classes from FXML documents. Many of these are targeted as extensions, features or plugins to existing development tools, such as SceneBuilder, Idea, Eclipse or NetBeans.
I suggest that interested readers review both this answer and other answers to this question, then look at their individual use-case and toolset chain and choose the solution which is most appropriate for them from the available choices.
There is nothing I know that does exactly what you propose in your question.
Likely this answer will probably end up pretty outdated over time.
Alternate Technologies
JRuby achieves most of your outlined benefits using a slightly different approach - it uses jRuby's dynamic programming magic to automatically create Ruby class members from the FXML dynamically a runtime.
Tom Schindl wrote a tool which generates Java code from FXML. Of the approaches listed in this answer, Tom's tool seems closest to your question.
SceneBuilder Skeletons
A similar Java code generator from FXML is available in SceneBuilder View | Show Sample Controller Skeleton feature, which is described in this blog post. When I use SceneBuilder, I use this feature all the time and try to keep my controllers really light so they are almost all auto generated code from the SceneBuilder skeleton feature.
It is slightly annoying though because it doesn't achieve a clean separation of generated code from hand written code, so you need to be careful when you do updates to the FXML and want to generate a new skeleton and copy and paste it over parts of your existing Controller (plus that is a slightly error prone manual operation that takes a little bit of developer time).
Source code for SceneBuilder is available if you want to see how it works.
Potential Build Tool Plugins
Such a code generation feature might make a worthwhile addition to some of the existing build tools in the JavaFX ecosystem, such as the JavaFX Maven plugin or JavaFX Gradle plugin (or a separate plugin in it's own right).
Future Development
I believe that Oracle are also working on a feature extension for FXML for a future JavaFX release (post Java 8) which compiles FXML directly to Java byte code (class files), bypassing the Java source code step. This kind of feature would probably achieve most of your outlined benefits.
It is possible with NetBeans version 8.
Open FXML , go to Source and click generate controller.
Edit: Now can be done in any IDE , Eclipse needs a plugin thought.
For Intellij Idea IDE users, FXMLManager to the rescue. See the plugin homepage
"When clicking right mouse button on .fxml file, there is new menu item "Update Controller from FXML".
Clicking this item will modify FXML Java Controller:
Remove all #FXML fields that are missing in FXML and their getters/setters
Add all #FXML fields that are missing in Controller
#Deprecate all ActionEvent methods that are missing in FXML
Create all ActionEvent methods that are missing from Controller"
As I know, there are two kind of solutions exist in netbeans.
First, netbeans's internal feature "Make Controller", which you can see with right mouse click on the fxml document. it will generate controller class which will work with FXMLLoader. The controller's java file name should be indicated in the fxml document. (left panel -> Controller -> Controller class)
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Second, netbeans's plugin "FXML 2 JAVA Converter", which you can install from menu (Tool -> Plugin -> Available Plugin -> FXML 2 JAVA Converter). and you can see "Generate Abstract Class" menu item with right mouse click on the fxml document. It will generate source code from fxml document and you can use it as an abstract class without using FXMLLoader like normal JavaFX project not JavaFXML project.
Now you can easily do it with eclipse Just do these simple steps :
Go to your fxml file that you want to create Controller for
Right Click and Click source
Click Generate Controller
Click here to see the Picture of How to do it.
If you're using IntelliJ ide, you may have to try FXML Helper plugin.
First, install the plugin from the File | Settings... | Plugins. After the installation restart the ide, Now right click on the .fxml document and select the FXML Helper menu. That`s all.
#Feuermurmel
no there is not any ways to generate automatically controller class for particula .fxml file.
you should define dynamically declare variable and method with anotation #fxml and set(bind) in scence builder.
Very basic loader question.
My WIMMOne watch uses Android 2.1 (version 7).
There are no orientation changes, etc. with a watch. The small screen does not have room for any layout changes. So no need to deal with any kind of layout change.
The app I am working on now simply reads from a cursor, and displays an open ended scrolling list. My first app had a fragment and that was a pain. So I decided since I don't need fragments I will do away with the complexities of fragments.
I START WITH:
public class PhoneListActivity extends Activity
implements LoaderManager.LoaderCallbacks <Cursor>;
THEN:
protected void onCreate(Bundle savedInstanceState)
{ super.onCreate(savedInstanceState);
setContentView(R.layout.phone_list_activity);
FINALLY:
getLoaderManager().initLoader(0, null, this);
BUT:
Because it is 2.1 I need to use:
getSupportLoaderManager().initLoader(0, null, this);
BUT: -
That generates compile errors, so I need to use:
public class PhoneListActivity extends FragmentActivity . . . (not just Activity)
BUT: -
It immediately crashes on load in the ContentProvider.
Postings in various sites refer to "Activities and ActivityFragments".
SO: QUESTION 1: Can my main class use "extends FragmentActivity" without setting up a separate fragment (ie: leave it just as an Activity).
QUESTION 2: If not, does that mean that to use a loader I must set up a separate fragment and deal with the issues of fragments?
Many thanks,
Clark
The answer is YES.
I redid part of the program and it now works without using fragments. It has the open ended scrolling being loaded from a cursor and basically the same structure above
I think something in handling my cursor was causing it to crash.
Clark
The application runs fine but i could not see my design in the designer view.
It says Cannot find resource named 'Locator'. Obviously, i did not change anything in the code, i just did the data binding using the data binding dialog...
anyone facing the same problem?
There are two known occurrences where this can happen.
If you change to Blend before you built the application, the DLLs are not available yet and this error can be seen. Building the application solves the issue.
There is a bug in Expression Blend where, if you are placing a user control in another user control (or Window in WPF), and the inner user control uses a global resource, the global resource cannot be found. In that case you will get the error too.
Unfortunately I do not have a workaround for the second point, as it is a Blend bug. I hope we will see a resolution for that soon, but it seems to be still there in Blend 4.
What you can do is
Ignore the error when working on the outer user control. When you work on the inner user control, you should see the design time data fine (not very satisfying I know).
Use the d:DataContext to set the design time data context in Blend temporarily.
Hopefully this helps,
Laurent
I've come up with a reasonably acceptable workaround to this problem since it doesn't appear to have been fixed in Blend 4:
In the constructor for your XAML UserControl just add the resources it needs, provided you're in design mode within Blend. This may be just the Locator, or also Styles and Converters as appropriate.
public partial class OrdersControl : UserControl
{
public OrdersControl()
{
// MUST do this BEFORE InitializeComponent()
if (DesignerProperties.GetIsInDesignMode(this))
{
if (AppDomain.CurrentDomain.BaseDirectory.Contains("Blend 4"))
{
// load styles resources
ResourceDictionary rd = new ResourceDictionary();
rd.Source = new Uri(System.IO.Path.Combine(Environment.CurrentDirectory, "Resources/Styles.xaml"), UriKind.Absolute);
Resources.MergedDictionaries.Add(rd);
// load any other resources this control needs such as Converters
Resources.Add("booleanNOTConverter", new BooleanNOTConverter());
}
}
// initialize component
this.InitializeComponent();
}
There may be some edge cases, but its working OK for me in the simple cases where before I'd get a big red error symbol. I'd LOVE to see suggestions on how to better solve this problem, but this at least allows me to animate user controls that otherwise are appearing as errors.
You could also extract out the creation of resources to App.xaml.cs:
internal static void CreateStaticResourcesForDesigner(Control element)
{
if (AppDomain.CurrentDomain.BaseDirectory.Contains("Blend 4"))
{
// load styles resources
ResourceDictionary rd = new ResourceDictionary();
rd.Source = new Uri(System.IO.Path.Combine(Environment.CurrentDirectory, "Resources/Styles.xaml"), UriKind.Absolute);
element.Resources.MergedDictionaries.Add(rd);
// load any other resources this control needs
element.Resources.Add("booleanNOTConverter", new BooleanNOTConverter());
}
}
and then in the control do this BEFORE InitializeComponent():
// create local resources
if (DesignerProperties.GetIsInDesignMode(this))
{
App.CreateStaticResourcesForDesigner(this);
}
Note: At some point in time this stopped working for me and I ended up hardcoding the path to the Styles.xaml because I got frustrated trying to figure out which directory I was in.
rd.Source = new Uri(#"R:\TFS-PROJECTS\ProjectWPF\Resources\Styles.xaml", UriKind.Absolute);
I'm sure I could find the right path with 5 minutes work, but try this if you're at your wits end like I was!
In MyUserControl.xaml, instead of:
DataContext="{Binding Main, Source={StaticResource Locator}
use:
d:DataContext="{Binding Main, Source={StaticResource Locator}
where "d" has been previously defined as:
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
The reason and workaround explained here
http://blogs.msdn.com/b/unnir/archive/2009/03/31/blend-wpf-and-resource-references.aspx
Look at (b) part of the post.
I had a similar problem with a user control resource.
I added this in my usercontrol xaml code:
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/GinaControls;component/Resources/GinaControlsColors.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
Where GinaControls is the namespace where the control class is declared and /Resources/GinaControlsColors.xaml is the project folder and xaml resource file name.
Hope this helps.
Just add this in your App.xaml.cs at the very beginning
here's my piece of code
[STATThread()]
static void main(){
App.Current.Resources.Add("Locator", new yournamespace.ViewModel.ViewModelLocator());
}
public App(){
main();
}
Make sure the Blend has opened the entire solution and NOT just the single project containing the views. I was right-clicking in Visual Studio and selecting Open In Expression Blend. To my surprize, Blend could not find the solution file, so it only opened the single project.
When I realized this, I launched Blend directly, pointed it to the solution file, and then Blend was able to find the ViewModelLocator in my view.