Hello everyone, In this article, We will bring Huawei Ads to your Flutter app!
What is the Ads Kit ?
Ads kit is used to obtain revenues. HUAWEI Ads Publisher Service utilizes Huawei’s vast user base and extensive data capabilities to deliver targeted, high quality ads to users.
Huawei Mobile Services Integration
Firstly, If you haven’t integrated Huawei Mobile Services to your app yet, please do it "https://medium.com/huawei-developers/android-integrating-your-apps-with-huawei-hms-core-1f1e2a090e98" here. After integration, you are ready to write some Dart code!
Flutter Integration
Get the latest version number from "https://pub.dev/packages/huawei_ads" official pub.dev package and add dependency to your pubspec.yaml;
Code:
dependencies:
huawei_ads: # Latest Version Number
Or download the package from "https://developer.huawei.com/consumer/en/doc/HMS-Plugin-Library-V1/flutter-sdk-download-0000001050196675-V1" Huawei Developer Website, extract the archive and add dependency as path;
Code:
dependencies:
huawei_ads:
path: # The path that you extracted archive to
huawei_ads:path: # The path that you extracted archive to
Usage
There are number of display options for Huawei Ads;
Banner Ads : Banner ads are rectangular images that occupy a spot at the top, middle, or bottom within an app’s layout. Banner ads refresh automatically at intervals. When a user taps a banner ad, the user is redirected to the advertiser’s page in most cases. "https://developer.huawei.com/consumer/en/doc/HMS-Plugin-Guides/banner-ads-0000001050436805-V1" for details
Interstitial ads : Interstitial ads are full-screen ads that cover the interface of an app. Such ads are displayed when a user starts, pauses, or exits an app, without disrupting the user’s experience. "https://developer.huawei.com/consumer/en/doc/HMS-Plugin-Guides/interstitial-ads-0000001050196804-V1" for details
Rewarded Ads : Rewarded ads are full-screen video ads that users opt to view in exchange for in-app rewards. "https://developer.huawei.com/consumer/en/doc/HMS-Plugin-Guides/rewarded-ads-0000001050315988-V1" for details
Splash ads : Splash ads are displayed immediately after an app is launched, even before the home screen of the app is displayed. "https://developer.huawei.com/consumer/en/doc/HMS-Plugin-Guides/splash-ads-0000001050439035-V1" for details
Native Ads : Native ads are typical ad materials that are displayed on the customized interface of an app so that they can fit seamlessly into the surrounding content in the app. "https://developer.huawei.com/consumer/en/doc/HMS-Plugin-Guides/native-ads-0000001050198817-V1" for details
Banner Ads
Banner Ad’s lifecycle can be managed from BannerAd object. Create it with your Ad Slot ID.
Code:
BannerAd bannerAd = BannerAd(
adSlotId: "testw6vs28auh3", // This is test slot id for banner ad
size: BannerAdSize.s320x50, // Banner size
adParam: AdParam(), // Special request options
bannerRefreshTime: 60, // Refresh time in seconds
listener: (AdEvent event, {int errorCode}) { // Event listener
print("Banner Ad event : $event");
},
);
Call loadAd() and show() functions sequentially to display the Banner Ad.
Code:
bannerAd.loadAd(); // Loading ad
bannerAd.show(); // Showing ad at the bottom of the page
r/HMSCore - How to use Huawei Ads Kit with Flutter
Banner Ad Page from Example Project
And finally don’t forget to destroy banner view at the desired point.
Code:
bannerAd.destroy(); // Destroying ad view
Interstitial Ads
You can display an Interstitial Ad with InterstitialAd object. Functions are same as Banner’s. Just call loadAd() and show() sequentially.
Code:
InterstitialAd interstitialAd = InterstitialAd(
adSlotId: "teste9ih9j0rc3", // This is test slot id for interstitial ad
adParam: AdParam(), // Special request options
listener: (AdEvent event, {int errorCode}) { // Event listener
print("Interstitial Ad event : $event");
},
);
interstitialAd.loadAd(); // Loading ad
interstitialAd.show(); // Showing ad full screen
... interstitialAd.destroy(); // Destroying full screen activity programatically
r/HMSCore - How to use Huawei Ads Kit with Flutter
Interstitial Ad Example
Reward Ads
Reward Ad flow can be started with a RewardAd object.
As you can see; if a user completes the reward process, you can use Reward object in listener callback.
Code:
RewardAd rewardAd = RewardAd(
listener: (RewardAdEvent event, {Reward reward, int errorCode}) { // Event listener for reward ad
print("RewardAd event : $event");
if (event == RewardAdEvent.rewarded) {
print('Received reward : ${jsonEncode(reward.toJson())}');
}
}
);
rewardAd.loadAd( // Loading ad
adSlotId: "testx9dtjwj8hp", // This is test slot id for reward ad
adParam: AdParam(), // Special request options
);
rewardAd.show(); // Showing ad full screen
... rewardAd.destroy(); // Destroying full screen activity programatically
r/HMSCore - How to use Huawei Ads Kit with Flutter
Collecting Reward Ad Events, Example Project
Splash Ads
With Splash Ad you can show non-skippable, highly customizable full screen ad from anywhere of your app.
Code:
SplashAd splashAd = SplashAd(
adType: SplashAdType.above, // Splash ad type
loadListener: (SplashAdLoadEvent event, {int errorCode}) { // loading events listened here
print("Splash Ad Load event : $event");
... // Handle how your app behave when splash ad started and ended
},
displayListener: (SplashAdDisplayEvent event) { // display events listened here
print("Splash Ad Display Event : $event");
},
);
splashAd.loadAd( // Loads and shows the splash ad
adSlotId: "testq6zq98hecj", // This is test slot id for splash ad
orientation: SplashAdOrientation.portrait, // Orientation
adParam: AdParam(), // Special request options
);
... splashAd.destroy(); // Destroying full screen activity programatically
Native Ads
Native Ads can be placed anywhere in your app as widget. Events can be listened with NativeAdController object and the widget can be customized with type and styles parameters.
Code:
NativeAd(
adSlotId: "testb65czjivt9", // small native template test id
controller: NativeAdController(), // native ad configuration and parameters
type: NativeAdType.small, // native ad type
styles: NativeStyles(), // native ad style
)
r/HMSCore - How to use Huawei Ads Kit with Flutter
Native Ads in list, Example Project
Huawei Ads Publisher Service
In this article we used test identifiers for ads. But; You need a Huawei Developer Account with Merchant Service enabled, for getting real Ad Slot ID. With these Ad Slot ID’s, Huawei can serve ads through your view and collect your revenue.
Further information, please take a look at these official docs;
"https://developer.huawei.com/consumer/en/doc/distribution/monetize/0603" App Integration Process
"https://developer.huawei.com/consumer/en/doc/distribution/monetize/Monetizeaddappandunit" Add App and Unit
Conclusion
Congratulations! It is really easy to display Huawei Ads in a Flutter app. If you run into a problem, write a comment. I would love to help!
Reference
"https://github.com/HMS-Core/hms-flutter-plugin/tree/master/flutter-hms-ads" Example Project - GitHub
"https://developer.huawei.com/consumer/en/hms/huawei-adskit/" Huawei Ads Kit
How much we can earn from ads kit. Is there any monetary system ?
Related
I'm looking at both a book and the beginning projects on developers.android.com and have a question. Google is utilizing the android:nClick to handle the click event which then points to a public method for execution....but the book is setting up click listeners by setting a View with the buttons ID and then executing the setOnClickListener. OnClickListenver has one method called OnClick which is then executed.
//book
public class MyGame extends Activity implements OnClickListener {
View continueButton = findViewById(R.id.continue_button);
continueButton.setOnClickListener(this);
View newButton = findViewById(R.id.new_button);
newButton.setOnClickListener(this);
View aboutButton = findViewById(R.id.about_button);
aboutButton.setOnClickListener(this);
View exitButton = findViewById(R.id.exit_button);
exitButton.setOnClickListener(this);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.about_button:
Intent i = new Intent(this, About.class);
startActivity(i);
break;
}
}
My question. Which is the better way to handle the Button Click? In looking at what google does in the XML, it seems a helluva lot cleaner....but curious on what the advantage is for the other way (and I cannot think of any). Search of the site didn't yield anything.
I dunno if the methods have advantages between them, however, I prefer the androidnClick method since the code looks clearer
You usually want to use the onClick method, as there is no benefit to implementing the OnClickListener (only more effort and possible performance loss).
If you want things like long clicks or other events, you will have to implement that (or define an inline listener), as there is no xml tag for those.
I think the OnClickListener is actually only there for consistency with these other classes
How to make your app accessible to users with vision impairment or other physical disabilities.
Your customer base probably includes many people with disabilities, whether you are aware of it or not. According to government figures, one person in five has some functional limitation, and eight percent of all users on the Web have disabilities. In the United States alone there are more than 30 million people with disabilities who can be affected by the design of computer software, and worldwide the number is much higher. Many countries/regions, including the United States, have laws that mandate accessibility at some level.
When it comes to reaching as wide a user base as possible, it's important to pay attention to accessibility in your Android application. Cues in your user interface that may work for a majority of users, such as a visible change in state when a button is pressed, can be less optimal if the user is visually impaired.
This post shows you how to make the most of the accessibility features built into the Android framework. It covers how to optimize your app for accessibility, leveraging platform features like focus navigation and content descriptions. It also covers how to build accessibility services, that can facilitate user interaction with any Android application, not just your own.
Techniques should be applied to solve them:
1. Developing Accessible Applications
Learn to make your Android application accessible. Allow for easy navigation with a keyboard or directional pad, set labels and fire events that can be interpreted by an accessibility service to facilitate a smooth user experience.
Add Content Descriptions
It's easy to add labels to UI elements in your application that can be read out loud to your user by a speech-based accessibility service like TalkBack . If you have a label that's likely not to change during the lifecycle of the application (such as "Pause" or "Purchase"), you can add it via the XML layout, by setting a UI element's android:contentDescription attribute, like in this example:
<Button
android:id=”@+id/pause_button”
android:src=”@drawable/pause”
android:contentDescription=”@string/pause”/>
However, there are plenty of situations where it's desirable to base the content description on some context, such as the state of a toggle button, or a piece selectable data like a list item. To edit the content description at runtime, use the setContentDescription() method, like this:
String contentDescription = "Select " + strValues[position];
label.setContentDescription(contentDescription);
Try to add content descriptions wherever there's useful information, but avoid the web-developer pitfall of labelling everything with useless information. For instance, don't set an application icon's content description to "app icon". That just increases the noise a user needs to navigate in order to pull useful information from your interface.
Try it out! Download TalkBack (an accessibility service published by Google) and enable it in Settings > Accessibility > TalkBack. Then navigate around your own application and listen for the audible cues provided by TalkBack.
Design for Focus Navigation
Your application should support more methods of navigation than the touch screen alone. Many Android devices come with navigation hardware other than the touchscreen, like a D-Pad, arrow keys, or a trackball. In addition, later Android releases also support connecting external devices like keyboards via USB or bluetooth.
In order to enable this form of navigation, all navigational elements that the user should be able to navigate to need to be set as focusable. This modification can be done at runtime using the View.setFocusable() method on that UI control, or by setting the android:focusable attrubute in your XML layout files.
Also, each UI control has 4 attributes, android:nextFocusUp, android:nextFocusDown, android:nextFocusLeft, and android:nextFocusRight, which you can use to designate the next view to receive focus when the user navigates in that direction. While the platform determines navigation sequences automatically based on layout proximity, you can use these attributes to override that sequence if it isn't appropriate in your application.
For instance, here's how you represent a button and label, both focusable, such that pressing down takes you from the button to the text view, and pressing up would take you back to the button.
<Button android:id="@+id/doSomething"
android:focusable="true"
android:nextFocusDown=”@id/label”
... />
<TextView android:id="@+id/label"
android:focusable=”true”
android:text="@string/labelText"
android:nextFocusUp=”@id/doSomething”
... />
Fire Accessibility Events
If you write a custom view, make sure it fires events at the appropriate times. Generate events by calling sendAccessibilityEvent(int), with a parameter representing the type of event that occurred. A complete list of the event types currently supported can be found in the AccessibilityEvent reference documentation.
As an example, if you want to extend an image view such that you can write captions by typing on the keyboard when it has focus, it makes sense to fire an TYPE_VIEW_TEXT_CHANGED event, even though that's not normally built into image views. The code to generate that event would look like this:
public void onTextChanged(String before, String after) {
...
if (AccessibilityManager.getInstance(mContext).isEnabled()) {
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
}
...
}
Test Your Application
Be sure to test the accessibility functionality as you add it to your application. In order to test the content descriptions and Accessibility events, install and enable an accessibility service. One option is Talkback , a free, open source screen reader available on Google Play. With the service enabled, test all the navigation flows through your application and listen to the spoken feedback.
2. Developing Accessibility Services
Develop an accessibility service that listens for accessibility events, mines those events for information like event type and content descriptions, and uses that information to communicate with the user. The example will use a text-to-speech engine to speak to the user.
Create Your Accessibility Service
An accessibility service can be bundled with a normal application, or created as a standalone Android project. The steps to creating the service are the same in either situation. Within your project, create a class that extends AccessibilityService.
package com.example.android.apis.accessibility;
import android.accessibilityservice.AccessibilityService;
public class MyAccessibilityService extends AccessibilityService {
...
@override
public void onAccessibilityEvent(AccessibilityEvent event) {
}
@override
public void onInterrupt() {
}
...
}
Like any other service, you also declare it in the manifest file. Remember to specify that it handles the android.accessibilityservice intent, so that the service is called when applications fire an AccessibilityEvent.
<application ...>
...
<service android:name=".MyAccessibilityService">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
. . .
</service>
...
</application>
If you created a new project for this service, and don't plan on having an application, you can remove the starter Activity class (usually called MainActivity.java) from your source. Remember to also remove the corresponding activity element from your manifest.
Configure Your Accessibility Service
You have two options for how to set these variables. The backwards-compatible option is to set them in code, using setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo). To do that, override the onServiceConnected() method and configure your service in there. @override
public void onServiceConnected() {
// Set the type of events that this service wants to listen to. Others
// won't be passed to this service.
info.eventTypes = AccessibilityEvent.TYPE_VIEW_CLICKED |
AccessibilityEvent.TYPE_VIEW_FOCUSED;
// If you only want this service to work with specific applications, set their
// package names here. Otherwise, when the service is activated, it will listen
// to events from all applications.
info.packageNames = new String[]
{"com.example.android.myFirstApp", "com.example.android.mySecondApp"};
// Set the type of feedback your service will provide.
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN;
// Default services are invoked only if no package-specific ones are present
// for the type of AccessibilityEvent generated. This service *is*
// application-specific, so the flag isn't necessary. If this was a
// general-purpose service, it would be worth considering setting the
// DEFAULT flag.
// info.flags = AccessibilityServiceInfo.DEFAULT;
info.notificationTimeout = 100;
this.setServiceInfo(info);
}
The second option is to configure the service using an XML file. Certain configuration options like canRetrieveWindowContent are only available if you configure your service using XML. The same configuration options above, defined using XML, would look like this:
<accessibility-service
android: accessibilityEventTypes="typeViewClicked|typeViewFocused"
android: packageNames="com.example.android.myFirstApp, com.example.android.mySecondApp"
android: accessibilityFeedbackType="feedbackSpoken"
android: notificationTimeout="100"
android: settingsActivity="com.example.android.apis.accessibility.TestBackActivity"
android: canRetrieveWindowContent="true"
/>
If you go the XML route, be sure to reference it in your manifest, by adding a <meta-data> tag to your service declaration, pointing at the XML file. If you stored your XML file in res/xml/serviceconfig.xml, the new tag would look like this:
<service android:name=".MyAccessibilityService">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data android:name="android.accessibilityservice"
android:resource="@xml/serviceconfig" />
</service>
Respond to AccessibilityEvents
Now that your service is set up to run and listen for events, write some code so it knows what to do when an AccessibilityEvent actually arrives! Start by overriding the onAccessibilityEvent(AccessibilityEvent) method. In that method, use getEventType() to determine the type of event, and getContentDescription() to extract any label text associated with the view that fired the event. @override
public void onAccessibilityEvent(AccessibilityEvent event) {
final int eventType = event.getEventType();
String eventText = null;
switch(eventType) {
case AccessibilityEvent.TYPE_VIEW_CLICKED:
eventText = "Focused: ";
break;
case AccessibilityEvent.TYPE_VIEW_FOCUSED:
eventText = "Focused: ";
break;
}
eventText = eventText + event.getContentDescription();
// Do something nifty with this text, like speak the composed string
// back to the user.
speakToUser(eventText);
...
}
Query the View Heirarchy for More Context
This step is optional, but highly useful. The Android platform provides the ability for an AccessibilityService to query the view hierarchy, collecting information about the UI component that generated an event, and its parent and children. In order to do this, make sure that you set the following line in your XML configuration:
android:canRetrieveWindowContent="true"
Once that's done, get an AccessibilityNodeInfo object using getSource(). This call only returns an object if the window where the event originated is still the active window. If not, it will return null, so behave accordingly. The following example is a snippet of code that, when it receives an event, does the following:
.Immediately grab the parent of the view where the event originated
.In that view, look for a label and a check box as children views
.If it finds them, create a string to report to the user, indicating the label and whether it was checked or not.
.If at any point a null value is returned while traversing the view hierarchy, the method quietly gives up.
// Alternative onAccessibilityEvent, that uses AccessibilityNodeInfo @override
public void onAccessibilityEvent(AccessibilityEvent event) {
AccessibilityNodeInfo source = event.getSource();
if (source == null) {
return;
}
// Grab the parent of the view that fired the event.
AccessibilityNodeInfo rowNode = getListItemNodeInfo(source);
if (rowNode == null) {
return;
}
// Using this parent, get references to both child nodes, the label and the checkbox.
AccessibilityNodeInfo labelNode = rowNode.getChild(0);
if (labelNode == null) {
rowNode.recycle();
return;
}
AccessibilityNodeInfo completeNode = rowNode.getChild(1);
if (completeNode == null) {
rowNode.recycle();
return;
}
// Determine what the task is and whether or not it's complete, based on
// the text inside the label, and the state of the check-box.
if (rowNode.getChildCount() < 2 || !rowNode.getChild(1).isCheckable()) {
rowNode.recycle();
return;
}
CharSequence taskLabel = labelNode.getText();
final boolean isComplete = completeNode.isChecked();
String completeStr = null;
if (isComplete) {
completeStr = getString(R.string.checked);
} else {
completeStr = getString(R.string.not_checked);
}
String reportStr = taskLabel + completeStr;
speakToUser(reportStr);
}
Now you have a complete, functioning accessibility service. Try configuring how it interacts with the user, by adding Android's text-to-speech engine, or using a Vibrator to provide haptic feedback!
3. Accessibility Checklist
Learn how to test your app for accessibility.
Testing Accessibility Features
Testing of accessibility features such as TalkBack, Explore by Touch and accessibility Gestures requires setup of your testing device. This section describes how to enable these features for accessibility testing.
Testing audible feedback
Audible accessibility feedback features on Android devices provide audio prompts that speaks the screen content as you move around an application. By enabling these features on an Android device, you can test the experience of users with blindness or low-vision using your application.
Audible feedback for users on Android is typically provided by TalkBack accessibility service and the Explore by Touch system feature. The TalkBack accessibility service comes preinstalled on most Android devices and can also be downloaded for free from Google Play.
Testing with TalkBack
The TalkBack accessibility service works by speaking the contents of user interface controls as the user moves focus onto controls. This service should be enabled as part of testing focus navigation and audible prompts.
To enable the TalkBack accessibility service:
Launch the Settings application.
Navigate to the Accessibility category and select it.
Select Accessibility to enable it.
Select TalkBack to enable it.
Note: While TalkBack is the most available Android accessibility service for users with disabilities, other accessibility services are available and may be installed by users.
Testing with Explore by Touch
The Explore by Touch system feature is available on devices running Android 4.0 and later, and works by enabling a special accessibility mode that allows users to drag a finger around the interface of an application and hear the contents of the screen spoken. This feature does not require screen elements to be focused using an directional controller, but listens for hover events over user interface controls.
To enable Explore by Touch:
Launch the Settings application.
Navigate to the Accessibility category and select it.
Select the TalkBack to enable it.
Note: On Android 4.1 (API Level 16) and higher, the system provides a popup message to enable Explore by Touch. On older versions, you must follow the step below.
Return to the Accessibility category and select Explore by Touch to enable it.
Note: You must turn on TalkBack first, otherwise this option is not available.
Testing focus navigation
Focus navigation is the use of directional controls to navigate between the individual user interface elements of an application in order to operate it. Users with limited vision or limited manual dexterity often use this mode of navigation instead of touch navigation. As part of accessibility testing, you should verify that your application can be operated using only directional controls.
You can test navigation of your application using only focus controls, even if your test devices does not have a directional controller. The Android Emulator provides a simulated directional controller that you can use to test navigation. You can also use a software-based directional controller, such as the one provided by the Eyes-Free Keyboard to simulate use of a D-pad on a test device that does not have a physical D-pad.
Testing gesture navigation
Gesture navigation is an accessibility navigation mode that allows users to navigate Android devices and applications using specific gestures. This navigation mode is available on Android 4.1 (API Level 16) and higher.
Note: Accessibility gestures provide a different navigation path than keyboards and D-pads. While gestures allow users to focus on nearly any on-screen content, keyboard and D-pad navigation only allow focus on input fields and buttons.
To enable gesture navigation:
Enable both TalkBack and the Explore by Touch feature as described in the Testing with Explore by Touch. When both of these features are enabled, accessibility gestures are automatically enabled.
You can change gesture settings using Settings > Accessibility > TalkBack > Settings > Manage shortcut gestures.
Note: Accessibility services other than TalkBack may map accessibility gestures to different user actions. If gestures are not producing the expected actions during testing, try disabling other accessibility services before proceeding.
Hello! I am working on a Google Maps Android API project and am having a difficult time. I have several markers on my map, which is an indoor location. I was able to change the color of the markers, but would like to change the icons as well. I've looked over the documentation from google and am trying to implement it but it is not working and I cannot go any further until it does. Id like to use custom images, but for now I want to just see it work. Im trying to use this code:
Code:
.icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow))
. I'm getting an error in Android studio saying that it can't resolve 'arrow' symbol. my full code is here: It doesn't seem like I'm missing any imports, so I'm not sure why this doesn't work.
Code:
package com.aa.maps;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.BitmapDescriptor;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
public Bitmap resizeMapIcons(String iconName, int width, int height){
Bitmap imageBitmap = BitmapFactory.decodeResource(getResources(),getResources().getIdentifier(iconName, "drawable", getPackageName()));
Bitmap resizedBitmap = Bitmap.createScaledBitmap(imageBitmap, width, height, false);
return resizedBitmap;
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Milwaukee, Wisconsin.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.getUiSettings().setZoomControlsEnabled(true);
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
// Add a marker in Milwaukee and move the camera
LatLng mpm = new LatLng(43.0408468, -87.921474);
LatLng planetarium = new LatLng(43.040622, -87.920798);
LatLng theater = new LatLng(43.040497, -87.920640);
LatLng marketplace = new LatLng(43.040779, -87.921717);
mMap.addMarker(new MarkerOptions().position(mpm).title("Milwaukee Public Museum").icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE))).showInfoWindow();
mMap.addMarker(new MarkerOptions().position(planetarium).title("The Daniel M. Soref National Geographic Planetarium").icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE)));
mMap.addMarker(new MarkerOptions().position(theater).title("The Daniel M. Soref National Geographic Theater").icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)));
mMap.addMarker(new MarkerOptions().position(marketplace).title("Museum Marketplace"));
mMap.addMarker(new MarkerOptions().position(marketplace).title("Museum Marketplace").icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)));
}
}
1. Java Swing Overview
Java uses a graphical user interface (GUI) to facilitate interaction between a user and a program. Java's Swing toolkit includes a number of classes to support GUI design. For example, component classes such as buttons, menus, lists, and text boxes, and container classes such as windows and panels.
The javax.swing package provides more powerful classes for designing GUIs. The UML class diagrams of some classes in the java.awt and javax.swing packages are as follows:
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
➢When learning GUI programming, you must have a good grasp of two concepts: container classes and component classes.
➢The JComponent class in the javax.swing package is a direct subclass of the Container class in the java.awt package and an indirect subclass of the Component class in the java.awt package. To learn GUI programming is to master some important subclasses of the Component class and their usage methods.
➢The following are the basics that are often mentioned in GUI programming.
(1) Java refers to an object created by a subclass or indirect subclass of a Component class as a component.
(2) In Java, an object created by a subclass or indirect subclass of a container is called a container.
(3) You can add components to the container. The Container class provides a public method: add(). A container can call this method to add a component to the container.
(4) The container invokes the removeAll() method to remove all components in the container. Invoke the remove(Component c) method to remove the component specified by parameter c in the container.
(5) Note that the container itself is also a component, so one container can be added to another container to achieve nesting of containers.
(6) Each time a new component is added or removed from the container, the container should call the validate() method to ensure that the components in the container can be displayed correctly.
2. Window
➢An instance of the JFrame class provided by Java is an underlying container, commonly referred to as a window. Other components must be added to the underlying container so that information can be exchanged with the operating system through this underlying container.
➢The JFrame class is an indirect subclass of the Container class. When you need a window, you can create an object using JFrame or its subclasses.
➢A window is also a container to which you can add components.
➢ It should be noted that windows are added by the system to the display screen by default, so adding one window to another container is not allowed.
2.1 Common JFrame Methods
(1) Construction method
1
2
3JFrame()//Create an untitled window.
JFrame(String s)// Create a window with the title s.
(2) Common methods
1public void setBounds(int a,int b,int width,int height)//
The initial position of the setting window is (a, b), that is, a pixel from the left side of the screen and b pixels from the upper side of the screen. The width of the window is width and the height is height.
1public void setSize(int width,int height)//
Sets the size of the window.
1public void setLocation(int x,int y)//
Sets the position of the window. The default position is (0, 0).
1public void setLocation(int x,int y)//
Specifies whether the window is visible. By default, the window is invisible.
1public void setResizable(boolean b)//
Specifies whether the window size can be adjusted. By default, the window size can be adjusted.
1public void dispose()//
Undoes the current window and releases the resources used by the current window.
1public void setExtendedState(int state)//
Sets the extended status of the window.
1public void setExtendedState(int state)//
This method is used to set how the program will handle after you click the close icon in the upper right corner of a window. For example: EXIT_ON_CLOSE
1public void setExtendedState(int state)//
Set the layout manager for this container.
1public Component add(Component comp)//
Appends the specified component to the end of this container.
1public void setMenuBar(MenuBar mb)//
Sets the menu bar of this frame to the specified menu bar.
1public void validate()//
Using the validate method causes the container to rearrange its subcomponents again. When you modify the subcomponents of this container (Add or remove components in the container, or change layout-related information) , the above method should be called.
The following example creates two windows using JFrame:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17import javax.swing.*;
import java.awt.*;
public class Example1 {
public static void main(String[] args) {
JFrame window1 = new JFrame("First Window ");
JFrame window2 = new JFrame("Second window ");
Container con = window1.getContentPane();
con.setBackground(Color.red);// Set the color of the window
window1.setBounds(60, 100, 188, 108);// Set the position and size of the window on the screen.
window2.setBounds(260, 100, 188, 108);
window1.setVisible(true);
window1.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);// Release the current window.
window2.setVisible(true);
window2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// Exit the program.
}
}
2.2 Menu Bar, Menu, Menu Item
(1) Menu bar
JMenubar, a subclass of the JComponent class, is responsible for creating the menu bar, and the JFrame class has a method for placing the menu bar in a window: setJMenuBar(JMenuBar bar); this method adds the menu bar to the top of the window.
The method for constructing the JMenuBar class of the menu bar is as follows:
1
2JMenuBar ();
JMenuBar Mbar = new JMenuBar ()
(2)Menu
JMenu, a subclass of the JComponent class, is responsible for creating menus.
Method of constructing the menu JMenu class:
1
2
3JMenu();
JMenu(String s);
JMenu m = new JMenu();
Common methods:
1
2
3public void add(JMenuItem item)// Adds a menu item specified by the item parameter to a menu.
public JMenuItem getItem(int n)// Gets the menu options at the specified index.
public int getItemCount()//Gets the number of menu options.
(3) Menu items
The JMenuItem class, a subclass of the JComponent class, creates menu items. The main methods of the JMenuItem class are as follows:
1
2
3JMenuItem(String s)// Constructs a menu item with a title.
JMenuItem(String text, Icon icon) // Construct menu items with titles and icons
public void setAccelerator(KeyStroke keyStroke)// Set shortcut keys for menu items
Example 2 Use the JFrame subclass to create a window with a menu in the main method:
WindowMenu.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42import javax.swing.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
public class WindowMenu extends JFrame {
JMenuBar menubar; //Declare a menu bar menubar
JMenu menu, subMenu; //Declare two menus menu,subMenu
JMenuItem itemLiterature, itemCooking; //Declare two menu items itemLiterature, itemCooking
public WindowMenu() {
}
public WindowMenu(String s, int x, int y, int w, int h) { // constructors, creating windows
init(s);// Window initialization
setLocation(x, y);// Position of the window
setSize(w, h);// Window size
setVisible(true);// Window Visible
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);// Actions after closing the window
}
void init(String s) {
setTitle(s); // Set the title of the window
menubar = new JMenuBar(); // Creates a menu bar menubar.
menu = new JMenu("Menu"); // Create a menu called Menu
subMenu = new JMenu("Sports Topics"); // Create a menu called Sports Topics
// Icons on the menu
// Using the icon class Icon, declare an icon, and then create its subclass ImageIcon class Create an icon
//Icon icon = new ImageIcon("a.gif");
itemLiterature = new JMenuItem("Literary Topics", new ImageIcon("a.gif")); // Create a menu itemLiterature with a title and icon
itemCooking = new JMenuItem("Cooking Topics ", new ImageIcon("b.gif")); // Create a menu itemCooking with a title and icon
itemLiterature.setAccelerator(KeyStroke.getKeyStroke('A')); // Set shortcut keys for the itemLiterature menu item
itemCooking.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_MASK)); // Setting shortcut keys for the itemCooking menu item
menu.add(itemLiterature);
menu.addSeparator(); // Add dividers between menus
menu.add(itemCooking);
menu.add(subMenu);
subMenu.add(new JMenuItem("soccer", new ImageIcon("c.gif")));
subMenu.add(new JMenuItem("basketball", new ImageIcon("d.gif")));
menubar.add(menu); // Add a menu to a menu bar
setJMenuBar(menubar); // Place the menu bar in the window
}
}
Example2.java
1
2
3
4
5public class Example2 {
public static void main(String[] args) {
WindowMenu win=new WindowMenu("Window with Menu",20,30,200,190);
}
}
3. Common Components and Layout
You can decompile a component in the command line window to view the attributes and common methods of the component. For example:
1C:\>javap javax.swing.JComponent
For example:
3.1 Common Components
1. Text box: A text box created by JTextField, a subclass of JComponent, allows users to enter a single line of text in the text box.
1
2
3
4
5
6// Construction Methods
JTextField();
JTextField(int columns);
// Common Methods
public String getText();
public void setText(String t);
2. Text area: A text area is created by JTexArea, a subclass of JComponent, to allow users to enter multiple lines of text in the text area.
1
2
3
4
5
6// Construction Methods
JTextArea();
JTextArea(int rows, int columns);
// Common Methods
public String getText();
public void setText(String t);
3. Buttons: Used by the JButton class, a subclass of JComponent, to create buttons that allow users to click buttons.
1
2
3
4
5// Construction Methods
JButton();
JButton(String text);
// Common Methods
public void addActionListener(ActionListener l);
4. Tags: The JLabel class, a subclass of JComponent, creates tags and provides prompt information for users.
1
2
3
4
5
6
7// Construction Methods
JLabel();
JLabel(String text);
JLabel(Icon image);
// Common Methods
public String getText();
public void setText(String t);
5. Selection box: The JCheckBox class, a subclass of JComponent, is used to create selection boxes that provide users with multiple choices.
1
2
3
4
5
6// Construction Methods
JCheckBox();
JCheckBox(String text);
// Common Methods
public void addItemListener(ItemListener l);
public void addActionListener(ActionListener l);
6. Radio button: Used by the JRadioButton class, a subclass of JComponent, to create a single selection box.
1
2
3
4
5// Construction Methods
JRadioButton();
JRadioButton(String text);
// Common Methods
public void addItemListener(ItemListener l);
7. Drop-down list: Used by the JComponent subclass JComboBox class to create a drop-down list.
1
2
3
4
5
6
7// Construction Methods
JComboBox();
JComboBox(Object[] items)
// Common Methods
public void addItemListener(ItemListener l);
public Object getSelectedItem();
public int getSelectedIndex();
8. Password box: The JPasswordField subclass of JComponent creates a password box. The default response character of the password box is *.
1
2
3
4
5
6
7
8
9// Construction Methods
JPasswordField();
JPasswordField(int columns);
// Common Methods
public String getText();
public void setText(String t);
public void setEchoChar(char c)// Use this method to reset the echo character.
public char[] getPassword()//This method returns the actual password.
The following example shows some common components:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43import javax.swing.*;
import java.awt.*;
class ComponentInWindow extends JFrame {
JCheckBox checkBox1, checkBox2; // Declare two check boxes
JRadioButton radioM, radioF; // Declare two radio boxes
ButtonGroup group; // Declare a button group
JComboBox<String> comboBox; // drop-down list
public ComponentInWindow() { // construction method
init(); // Calling the init() method
setVisible(true); // Window Visible
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
void init() {
setLayout(new FlowLayout()); // Set the layout manager for this container
comboBox = new JComboBox<>(); // Create a drop-down list
// Create two check boxes
checkBox1 = new JCheckBox("Love Java");
checkBox2 = new JCheckBox("I like data structures.");
group = new ButtonGroup();
radioM = new JRadioButton("male");
radioF = new JRadioButton("female");
group.add(radioM);
group.add(radioF); // Single-choice is supported only by grouping.
add(checkBox1);
add(checkBox2);
add(radioM);
add(radioF);
comboBox.addItem("Object-oriented");
comboBox.addItem("Minimum Spanning Tree(MST)");
add(comboBox);
}
}
public class Example9_3 {
public static void main(String[] args) {
ComponentInWindow win = new ComponentInWindow();
win.setBounds(100, 100, 450, 260);
win.setTitle("Common Components");
}
}
3.2 Common Containers
JComponent is a subclass of Container. Therefore, all components created by JComponent subclasses are containers. Containers are often used to add components. The JFrame is the bottom container, and the containers mentioned in this section are traditionally called intermediate containers, which must be added to the bottom container to function.
1. JPanel panel:
1
2
3
4
5// Construction Methods
JPanel();
// For example: JPanel p = new JPanel();
// Common Methods
public void add();
Create a panel using JPanel, add components to the panel, and add the panel to other containers. The default layout for the JPanel panel is the FlowLayout layout.
2. JTabbedPane Tab Pane
You can use the JTabbedPane container as an intermediate container.
When a user adds a component to the JTabbedPane container, the JTabbedPane container automatically assigns a tab to the component. That is, a tab corresponds to a component.
The components corresponding to each tab are stacked in the JTabbedPane container. When a user clicks a tab, the JTabbedPane container displays the components corresponding to the tab.
The tabs are by default at the top of the JTabbedPane container, arranged from left to right.
The JTabbedPane container can use:
add(String text,Component c);
Method to add component c to the JTabbedPane container and specify that the text prompt for the tab corresponding to component c is text.
3. Scroll PaneJscrollPane:
You can add only one component to the scroll pane. You can place a component in a scroll pane and view the component through the scroll bar.
JTextArea does not come with a scroll bar, so you need to place the text area in a scrolling pane.
For example:
1JScrollPane scroll = new JScrollPane(new JTextArea());
4. Split Pane JSplitPane
A split pane is a container that is divided into two parts. There are two types of split panes: horizontal split and vertical split.
Horizontal split panes are divided into left and right parts by a split line. A component is placed on the left and a component is placed on the right. The split line can be moved horizontally. Splitting a pane vertically uses a split line to divide the pane into two parts, with one component on top and one component on bottom. The split line moves vertically.
/* Two Common Construction Methods of JSplitPane*/
JSplitPane(int a,Component b,Component c)
// Parameter a is set to the static constant HORIZONTAL SPLIT or VERTICAL _SPLIT of JSplitPane to determine whether to split horizontally or vertically.
// The last two parameters determine which component to place.
JSplitPane(int a, boolean b,Component c,Component d)
// Parameter a is set to the static constant HORIZONTAL SPLIT or VERTICAL_ SPLIT of JSplitPane to determine whether to split horizontally or vertically.
// Parameter b determines whether the component changes continuously as the split line moves (true is continuous).
5. JLayeredPane Layered Pane
If components added to a container often need to deal with overlap, consider adding components to the hierarchical pane. The hierarchical pane is divided into five layers. The hierarchical pane uses add(Jcomponent com, int layer).
Add component com and specify the layer where com is located. The value of layer is a class constant in the JLayeredPane class.
DEFAULT LAYER、PALETTE I AYER、MODAL LAYER、POPUP I AYER、DRAG LAYER。
DEFAULT_LAYER is the bottom layer. If components added to DEFAULT_LAYER overlap with components of other layers, they are obscured by other components. The DRAG Layer layer is the top layer. If many components are added to the layering pane, you can place a component on the DRAG_Layer layer when you move the component. In this way, the component is not blocked by other components when you move the component. If components that are added to the same layer overlap, the components that are added later obscure the components that are added earlier. The layered pane invokes public void setLayer(Component c, int layer) to reset the layer where component c resides, and invokes public int getLayer(Component c) to obtain the number of layers where component c resides.
3.3 Common Layouts
➢ When adding a component to a container, you want to control the location of the component in the container, which requires learning about layout design.
➢ We will introduce the FlowLayout, BorderLayout, CardLayout, GridLayout layout classes in the java.awt package and the BoxLayout layout classes in the java.swing.border package.
➢ Containers can be used in the following ways:
setLayout(layout object);
to set your own layout and control the placement of components in the container.
1. FlowLayout Layout: is the default layout for JPanel-type containers.
1) Create a layout object: FlowLayout flow=new FlowLayout();
2) Container con uses layout objects: == con.setLayout(flow); ==
3) The con can use the add method provided by the Container class to add components to the container sequentially.
The FlowLayout layout object invokes the corresponding method to reset the alignment mode of the layout.
For example: public void setAlignment(int align)
2. BorderLayout Layout:
The BorderLayout layout is the default layout for Window containers.
If the container con in the BorderLayout layout is used, you can use the add method to add component b to the central area: con.add(b, BorderLayout.CENTER).
or con.add(BorderLayour.CENTER, b);
3. CardLayout Layout: The general steps to use CardLayout are as follows:
1) Create the CardLayout object CardLayout card=new CardLayout();
2) Set the layout con.setLayout(card) for the container.
3) The container calls add(String s, Component b) to add component b to the container, and gives the code s for displaying the component.
4) The layout object card uses the show() method provided by the CardLayout class to display the component code s in the container con:
card.show(con,s);
Containers using CardLayout can hold multiple components, but in reality, containers can only select one of these components at a time to display, like a stack of "playing cards" that can only display the most at a time. As in the previous one, the components shown will take up all the container space, in sequence.
4. GridLayout Layout:
The GridLayout layout strategy divides the container into several rows by several columns, and the components are located in these small grids. The general steps for the GridLayout Layout Editor are as follows:
1) Create a layout object and specify the number of rows (m) and columns for grid division.
GridLayout grid=new new GridLayout(10, 8);
2) Use the container of the GridLayout layout to call the add (Component c) method to add component c to the container.
5. null layout
You can set the layout of a container to null (empty layout). An empty layout container can accurately locate the position and size of components in the container. The setBounds(int a, int b, int width, int height) method is a method owned by all components. A component can call this method to set its size and position in the container.
For example, p is a container,
p.setLayout(null);
Set the layout of p to an empty layout.
Adding a component c to an empty layout container p requires two steps.
First, container p uses the add(c) method to add a component, and then component c calls the setBounds(int a, int b, int width, int height) method to set the location and size of the component in container p. Each component is a rectangular structure, and parameters a and b in the method are location coordinates of an upper left corner of the component c in the container p, that is, the component is a pixel from the left side of the container p, and b pixels from the upper side of the container p, width, and height is the width and height of component c.
The following example adds a tab pane in the center of the window with a grid layout panel and an empty layout panel:
Example.java
1
2
3
4
5public class Example {
public static void main(String[] args) {
new ShowLayout();
}
}
ShowLayout.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26import java.awt.*;
import javax.swing.*;
public class ShowLayout extends JFrame {
PanelGridLayout panelGridLayout; // Panel for Grid Layout
PanelNullLayout panelNull; // Panel with empty layout
JTabbedPane p; // Tab Pane
ShowLayout() {
panelGridLayout = new PanelGridLayout();//Create a panel for a grid layout
panelNull = new PanelNullLayout();//Create a panel with an empty layout
p = new JTabbedPane();//Create a tab for selecting which panel layout
p.add("Panel for Grid Layout", panelGridLayout);// Adding a Grid Layout Board to the Tab Pane
p.add("Panel with empty layout", panelNull);// Add an empty layout panel to the Tab Pane
add(p, BorderLayout.CENTER);// Adding a Tab Pane to a ShowLayout Panel
// Add Buttons to Large Panels
add(new JButton("Form is BorderLayout Layout"), BorderLayout.NORTH);
add(new JButton("South"), BorderLayout.SOUTH);
add(new JButton("West"), BorderLayout.WEST);
add(new JButton("East"), BorderLayout.EAST);
setBounds(10, 10, 570, 390);
setVisible(true);// Window Visible
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
validate();
}
}
PanelGridLayout.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20import java.awt.*;
import javax.swing.*;
public class PanelGridLayout extends JPanel {// Mesh cloth panel
PanelGridLayout() {
GridLayout grid = new GridLayout(12, 12); // Grid Layout
setLayout(grid);
Label label[][] = new Label[12][12];
for (int i = 0; i < 12; i++) {
for (int j = 0; j < 12; j++) {
label[j] = new Label();
if ((i + j) % 2 == 0)
label[j].setBackground(Color.black);
else
label[j].setBackground(Color.white);
add(label[j]);// Add a small mesh to the panel
}
}
}
}
PanelNullLayout.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16import javax.swing.*;
public class PanelNullLayout extends JPanel {// Blank Page Layout
JButton button;// “OK” button
JTextField text;// text box
PanelNullLayout() {
setLayout(null); // Empty Layout
button = new JButton("OK "); // Create “OK” button
text = new JTextField();//Create Text Box
add(text); // Add a text box to the PanelNullLayout panel
add(button); // Add a button to the PanelNullLayout panel
text.setBounds(100, 30, 90, 30); // Set Text Box Size
button.setBounds(190, 30, 66, 30); // Set Button Size
}
}
The following figure shows the running screenshot.
6. BoxLayout Layout
The class (static) method createHorizontalBox() of the Box class obtains a row-type box container.
Use the class (static) method createVerticalBox() of the Box class to obtain a column-type box container.
To control the distance between components in a box layout container, you need to use either horizontal or vertical braces.
In the following example, there are two column-type box containers, boxVOne, boxVTwo, and one row-type box container, boxH. Add boxVOne, boxVTwo to boxH and add horizontal braces between them.
Example.java
1
2
3
4
5
6
7
8public class Example {
public static void main(String[] args) {
WindowBoxLayout win = new WindowBoxLayout();
win.setBounds(100, 100, 310, 260);
win.setTitle("Nested Box Layout Container");
}
}
WindowBoxLayout .java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27import javax.swing.*;
public class WindowBoxLayout extends JFrame {
Box boxH; // Row Box
Box boxVOne, boxVTwo; // column box
public WindowBoxLayout() {
setLayout(new java.awt.FlowLayout());
init();
setVisible(true);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
void init() {
boxH = Box.createHorizontalBox();//Get a row box container
boxVOne = Box.createVerticalBox();//Get a column-type box container
boxVTwo = Box.createVerticalBox();//Get a column-type box container
boxVOne.add(new JLabel("姓名:"));// Adding Name Labels to Column-Type Box Containers
boxVOne.add(new JLabel("职业:"));// Add occupational labels to column box containers
boxVTwo.add(new JTextField(10));// Add the name text box for column-shaped box containers.
boxVTwo.add(new JTextField(10));// Add career input box for column-shaped box containers
boxH.add(boxVOne);
boxH.add(Box.createHorizontalStrut(10));
boxH.add(boxVTwo);
add(boxH);
}
}
The command output is as follows:
By Codeplus.
Original link: https://blog.csdn.net/m0_46518461/article/details/115876407
The launch of HMS Core Video Editor Kit 6.2.0 has brought two notable highlights: various AI-empowered capabilities and flexible integration methods. One method is to integrate the fundamental capability SDK, which is described below.
PreparationsFor details, please check the official document.
Code DevelopmentConfiguring a Video Editing Project
1. Set the authentication information for your app through an API key or access token.
Use the setAccessToken method to set an access token when the app is started. The access token needs to be set only once.
Code:
MediaApplication.getInstance().setAccessToken("your access token");
Use the setApiKey method to set an API key when the app is started. The API key needs to be set only once.
Code:
MediaApplication.getInstance().setApiKey("your ApiKey");
2. Set a License ID.
This ID is used to manage your usage quotas, so ensure that the ID is unique.
Code:
MediaApplication.getInstance().setLicenseId("License ID");
3. Initialize the running environment for HuaweiVideoEditor.
When creating a video editing project, first create a HuaweiVideoEditor object and initialize its running environment. When exiting a video editing project, release the HuaweiVideoEditor object.
Create a HuaweiVideoEditor object.
Code:
HuaweiVideoEditor editor = HuaweiVideoEditor.create(getApplicationContext());
Specify the position for the preview area.
This area renders video images, which is implemented by creating SurfaceView in the fundamental capability SDK. Ensure that the preview area position on your app is specified before creating this area.
Code:
<LinearLayout
android:id="@+id/video_content_layout"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@color/video_edit_main_bg_color"
android:gravity="center"
android:orientation="vertical" />
// Specify the preview area position.
LinearLayout mSdkPreviewContainer = view.findViewById(R.id.video_content_layout);
// Set the layout of the preview area.
editor.setDisplay(mSdkPreviewContainer);
Initialize the running environment. If the license verification fails, LicenseException will be thrown.
After the HuaweiVideoEditor object is created, it has not occupied any system resource. You need to manually set the time for initializing the running environment of the object. Then, necessary threads and timers will be created in the fundamental capability SDK.
Code:
try {
editor.initEnvironment();
} catch (LicenseException error) {
SmartLog.e(TAG, "initEnvironment failed: " + error.getErrorMsg());
finish();
return;
}
4. Add a video or image.
Create a video lane and add a video or image to the lane using the file path.
Code:
// Obtain the HVETimeLine object.
HVETimeLine timeline = editor.getTimeLine();
// Create a video lane.
HVEVideoLane videoLane = timeline.appendVideoLane();
// Add a video to the end of the video lane.
HVEVideoAsset videoAsset = videoLane.appendVideoAsset("test.mp4");
// Add an image to the end of the video lane.
HVEImageAsset imageAsset = videoLane.appendImageAsset("test.jpg");
5. Add audio.
Create an audio lane and add audio to the lane using the file path.
Code:
// Create an audio lane.
HVEAudioLane audioLane = timeline.appendAudioLane();
// Add an audio asset to the end of the audio lane.
HVEAudioAsset audioAsset = audioLane.appendAudioAsset("test.mp3");
6. Add a sticker and text.
Create a sticker lane and add a sticker and text to the lane. A sticker needs to be added using its file path, while the text needs to be added by specifying its content.
Code:
// Create a sticker lane.
HVEStickerLane stickerLane = timeline.appendStickerLane();
// Add a sticker to the end of the lane.
HVEStickerAsset stickerAsset = stickerLane.appendStickerAsset("test.png");
// Add text to the end of the lane.
HVEWordAsset wordAsset = stickerLane.appendWord("Input text",0,3000);
7. Add a special effect.
Special effects are classified into the external special effect and embedded special effect.
Add an external special effect to an effect lane. This special effect can be applied to multiple assets, and its duration can be adjusted.
Code:
// Create an effect lane.
HVEEffectLane effectLane = timeline.appendEffectLane();
// Create a color adjustment effect with a duration of 3000 ms. Add it to the 0 ms playback position of the lane.
HVEEffect effect = effectLane.appendEffect(new HVEEffect.Options(HVEEffect.EFFECT_COLORADJUST, "", ""), 0, 3000);
Add an embedded special effect to an asset. Such a special effect can be applied to a single asset. The special effect's duration is the same as that of the asset and cannot be adjusted.
Code:
// Create an embedded special effect of color adjustment.
HVEEffect effect = videoAsset.appendEffectUniqueOfType(new HVEEffect.Options(HVEEffect.EFFECT_COLORADJUST, "", ""), ADJUST);
8. Play a timeline.
To play a timeline, specify its start time and end time. The timeline will play from its start time to end time at a fixed frame rate, and the image and sound in the preview will play simultaneously. You can obtain the playback progress, playback pause, payback completion, and playback failure via the registered callback.
Code:
// Register the playback progress callback.
editor.setPlayCallback(callback);
// Play the complete timeline.
editor.playTimeLine(timeline.getStartTime(), timeline.getEndTime());
9. Export a video.
After the editing is complete, export a new video using the assets in the timeline via the export API. Set the export callback to listen to the export progress, export completion, or export failure, and specify the frame rate, resolution, and path for the video to be exported.
Code:
// Path for the video to be exported.
String outputPath =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
+ File.separator + Constant.LOCAL_VIDEO_SAVE_PATH
+ File.separator + VideoExportActivity.getTime() + ".mp4";
// Resolution for the video to be exported.
HVEVideoProperty videoProperty = new HVEVideoProperty(1920, 1080);
// Export the video.
HVEExportManager.exportVideo(targetEditor, callback, videoProperty, outputPath);
Managing Materials
After allocating materials, use APIs provided in the on-cloud material management module to query and download a specified material. For details, please refer to the description in the official document.
Integrating an AI-Empowered Capability
The fundamental capability SDK of Video Editor Kit provides multiple AI-empowered capabilities including AI filter, track person, moving picture, and AI color, for integration into your app. For more details, please refer to the instruction in this document.
AI Filter
Lets users flexibly customize and apply a filter to their imported videos and images.
Code:
// Create an AI algorithm engine for AI filter.
HVEExclusiveFilter filterEngine = new HVEExclusiveFilter();
// Initialize the engine.
mFilterEngine.initExclusiveFilterEngine(new HVEAIInitialCallback() {
@Override
public void onProgress(int progress) {
// Initialization progress.
}
@Override
public void onSuccess() {
// The initialization is successful.
}
@Override
public void onError(int errorCode, String errorMessage) {
// The initialization failed.
}
});
// Create an AI filter of the extract type from an image, by specifying the image bitmap and filter name.
// The filter ID is returned. Using the ID, you can query all information about the filter in the database.
String effectId = mFilterEngine.createExclusiveEffect(bitmap, "AI filter 01");
// Add the filter for the first 3000 ms segment of the effect lane.
effectLane.appendEffect(new HVEEffect.Options(
HVEEffect.CUSTOM_FILTER + mSelectName, effectId, ""), 0, 3000);
Color Hair
Changes the hair color of one or more persons detected in the imported image, in just a tap. The color strength is adjustable.
Code:
// Initialize the AI algorithm for the color hair effect.
asset.initHairDyeingEngine(new HVEAIInitialCallback() {
@Override
public void onProgress(int progress) {
// Initialization progress.
}
@Override
public void onSuccess() {
// The initialization is successful.
}
@Override
public void onError(int errorCode, String errorMessage) {
// The initialization failed.
}
});
// Add the color hair effect by specifying a color and the default strength.
asset.addHairDyeingEffect(new HVEAIProcessCallback() {
@Override
public void onProgress(int progress) {
// Handling progress.
}
@Override
public void onSuccess() {
// The handling is successful.
}
@Override
public void onError(int errorCode, String errorMessage) {
// The handling failed.
}
}, colorPath, defaultStrength);
// Remove the color hair effect.
asset.removeHairDyeingEffect();
Moving Picture
Animates one or more persons in the imported image, so that they smile, nod, or more.
Code:
// Add the moving picture effect.
asset.addFaceReenactAIEffect(new HVEAIProcessCallback() {
@Override
public void onProgress(int progress) {
// Handling progress.
}
@Override
public void onSuccess() {
// The handling is successful.
}
@Override
public void onError(int errorCode, String errorMessage) {
// The handling failed.
}
});
// Remove the moving picture effect.
asset.removeFaceReenactAIEffect();
This article presents just a few features of Video Editor Kit. For more, check here.
To learn more, please visit:
>> HUAWEI Developers official website
>> Development Guide
>> Reddit to join developer discussions
>> GitHub to download the sample code
>> Stack Overflow to solve integration problems
Follow our official account for the latest HMS Core-related news and updates.