眾所周知,安卓應用開發經過這麼多年的發展相對成熟和穩定,鴻蒙 OS 作為後來者相容一個成熟的開發體系會節省很多推廣和開發成本。
但在實際開發中,程式碼層面仍然有很多細節上的差異,會給初次開發人員造成困擾。
本寶典旨在彙總實際開發中第三方件接入時的程式碼差異,以及幫助開發人員更好的進行開發作業,由於目前接觸的開發型別有限,所彙總的內容多少會有疏漏,後期我們會進一步完善和補全。
基礎功能
01獲取螢幕解析度
安卓:
getWindowManager().getDefaultDisplay();
鴻蒙:
Optional<Display> display = DisplayManager.getInstance().getDefaultDisplay(this.getContext());Point pt = new Point();display.get().getSize(pt);
02隱藏標題欄 TitleBar
安卓:略。
鴻蒙:confi.json 中新增如下描述。
""metaData"":{ ""customizeData"":[ { ""name"": ""hwc-theme"", ""value"": ""androidhwext:style/Theme.Emui.NoTitleBar"", ""extra"":"""" } ] }
03獲取螢幕密度
安卓:
Resources.getSystem().getDisplayMetrics().density
鴻蒙:
// 獲取螢幕密度Optional<Display> display = DisplayManager.getInstance().getDefaultDisplay(this.getContext()); DisplayAttributes displayAttributes = display.get().getAttributes();//displayAttributes.xDpi;//displayAttributes.yDpi;
04獲取上下文
安卓:
context
鴻蒙:
getContext()
05元件的父類
安卓:
android.view.View; class ProgressBar extends View
鴻蒙:
class ProgressBar extends Component
06沉浸式顯示
安卓:略。
鴻蒙:兩種方式。
A:在config.json ability 中新增。
"metaData"": { ""customizeData"": [ { ""extra"": """", ""name"": ""hwc-theme"", ""value"": ""androidhwext:style/Theme.Emui.Light.NoTitleBar"" } ]}
B:在 AbilitySlice 的 onStart 函式內增加如下程式碼,注意要在 setUIContent 之前。
getWindow().addFlags(WindowManager.LayoutConfig.MARK_TRANSLUCENT_STATUS);
07獲取執行時許可權
安卓:
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, 1)
鴻蒙:
requestPermissionsFromUser( new String[]{""ohos.permission.READ_MEDIA"", ""ohos.permission.WRITE_MEDIA"", ""ohos.permission.READ_USER
佈局&元件
01頁面跳轉(顯示跳轉)
安卓:
A.從 A 跳轉至 B,沒有引數,並且不接收返回值。
Intent intent = new Intent(); intent.setClass(A.this, B.class); startActivity(intent);
B.從 A 跳轉至 B,有引數,不接收返回值。
Intent intent = new Intent(this, B.class); intent.putExtra(""name"", ""lily""); startActivity(intent);
C.從 A 跳轉至 B,有引數,接收返回值。
Intent intent = new Intent(this, B.class);intent.putExtra(""name"", ""lily"");startActivityForResult(intent, 2);
鴻蒙:
A.從 A 跳轉至 B,沒有引數,並且不接收返回值。
present(new BSlice(), new Intent());
B.從 A 跳轉至 B,有引數,不接收返回值。
Intent intent = new Intent(); Operation operation = new Intent.OperationBuilder() .withDeviceId("""") .withBundleName(""com.test"") .withAbilityName(""com.test.BAbility"") .build(); intent.setParam(""name"",""lily""); intent.setOperation(operation); startAbility(intent);
C.從 A 跳轉至 B,有引數,接收返回值。
Intent intent = new Intent(); Operation operation = new Intent.OperationBuilder() .withDeviceId("""") .withBundleName(""com.test"") .withAbilityName(""com.test.BAbility"") .build(); intent.setParam(""name"",""lily""); intent.setOperation(operation); startAbilityForResult(intent,100);
02頁面跳轉(隱式跳轉)
安卓:
A.配置
<activity android:name="".B""> <intent-filter> <action android:name=""com.hly.view.fling""/> </intent-filter> </activity>
B.啟動
Intent intent = new Intent(); intent.setAction(""com.hly.view.fling""); intent
鴻蒙:
A.在 config.json 檔案 ability 中新增以下資訊
"skills"":[ { ""actions"":[ ""ability.intent.gotopage"" ] }]
B.在 MainAbility 的 onStart 函式中,增加頁面路由
addActionRoute( ""ability.intent.gotopage"", BSlice.class.getName());
C.跳轉
Intent intent = new Intent(); intent.setAction(""ability.intent.gotopage""); startAbility(intent);
03頁面碎片
安卓:Fragment。
鴻蒙:Fraction。
A:Ability 繼承 FractionAbility
B:獲取 Fraction 排程器
getFractionManager().startFractionScheduler()
C:構造 Fraction
D:呼叫排程器管理 Fraction
FractionScheduler.add()FractionScheduler.remove()FractionScheduler.replace()
備註:參考 demo。
https://www.jianshu.com/p/58558dc6673a
04從 xml 檔案建立一個元件例項
安卓:
LayoutInflater.from(mContext).inflate(R.layout.banner_viewpager_layout, null);
鴻蒙:
LayoutScatter.getInstance(getContext()).parse(ResourceTable.Layout_ability_main, null, false);
05元件自定義繪製
安卓:
ImageView.setImageDrawable(Drawable drawable);
並重寫 Drawable 的 draw 函式。
鴻蒙:
Component.addDrawTask(Component.DrawTask task);
並實現 Component.DrawTask 介面的 onDraw 函式。
06自定義元件的自定義屬性(在xml中使用)
安卓:需要 3 步。
A.在 values/attrs.xml,在其中編寫 styleable 和 item 等標籤元素。
B.在 layout.xml 中,增加:
xmln:app= ""http://schemas.android.com/apk/res/-auto""
C.在自定義元件的建構函式中,呼叫 array.getInteger(R.styleable.***, 100); 獲取屬性。
鴻蒙:只需 2 步。
A. 在元件定義的 layout.xml 中增加:
xmlns:app=""http://schemas.huawei.com/apk/res/ohos""
然後就可以使用 app:***(*** 為任意字串)來增加自定義屬性了,為了區分建議加上元件名字首。
B. 在自定義元件的帶 AttrSet 引數的建構函式中,使用下面程式碼獲取屬性。
attrSet.getAttr(""***"").get().getStringValue();
07觸控事件
安卓:
android.view.MotionEvent
鴻蒙:
ohos.multimodalinput.event.TouchEvent
08事件處理
安卓:
android.os.Handler
鴻蒙:
ohos.eventhandler.EventHandler
09控制元件觸控事件回撥
安卓:
android.view.View.OnTouchListener
鴻蒙:
ohos.agp.components.Component.TouchEventListener
10輪播圖繼承的父類
安卓:
extends ViewPager
鴻蒙:
extends PageSlider
11實現監聽輪播圖元件事件
安卓:
implements PageSlider.PageChangedListener
鴻蒙:
Implements OnPageChangedListener
12touch 事件監聽
安卓:直接重寫 onTouchEvent。
鴻蒙:繼承 Component.TouchEventListener,然後在構造方法中設定監聽 setTouchEventListener(this::onTouchEvent); 實現 onTouchEvent。
安卓:
event.getX(), event.getY()
鴻蒙:
MmiPoint point = touchEvent.getPointerPosition(touchEvent.getIndex());
14調節滾輪中內容間距
安卓:
setLineSpacingMultiplier(float f)
鴻蒙:
setSelectedNormalTextMarginRatio(float f)
15滾輪定位
安卓:
setPosition
鴻蒙:
setValue
16Layout 佈局改變監聽
安卓:
View.OnLayoutChangeListener
鴻蒙:
Component.LayoutRefreshedListener
17元件容器
安卓:
ViewGroup
鴻蒙:
ComponentContainer
18新增元件
安卓:
addView()
鴻蒙:
addComponent()
19動態列表的介面卡
安卓:
extends RecyclerView.Adapter<>
鴻蒙:
extends RecycleItemProvider
20動態列表
安卓:
RecyclerView
鴻蒙:
ListContainer
21文字域動態監聽
安卓:
TextWatcher
鴻蒙:
Component.ComponentStateChangedListener
22元件繪製自定義佈局
安卓:重寫 onLayout(boolean changed, int left, int top, int right, int bottom)。
鴻蒙:重寫 Component.LayoutRefreshedListener 的 onRefreshed 方法。
23List 元件
安卓:ListView。
鴻蒙:ListContainer。
24設定背景顏色
安卓:
setBackgroundColor(maskColor);
鴻蒙:
// 建立背景元素ShapeElement shapeElement = new ShapeElement();// 設定顏色shapeElement.setRgbColor(new RgbColor(255, 0, 0));view.setBackground(shapeElement);
25可以在控制元件上、下、左、右設定圖示,大小按比例自適應
安卓:
setCompoundDrawablesWithIntrinsicBounds
鴻蒙:
setAroundElements
26RadioButton 元件在 xml 中如何設定 checked 屬性
安卓:在 xml 中可以設定。
鴻蒙:
radioButton = findComponentById();radioButton.setChecked(true);
備註:sdk 2.0 後 xml 中沒有了 checked 屬性,如果使用,可以在 java 程式碼中實現。
27文字域動態監聽
安卓:
TextWatcher
鴻蒙:
Component.ComponentStateChangedListener
28顏色類
安卓:
java.awt.Color
鴻蒙:
安卓:略。
鴻蒙:
VectorElement vectorElement = new VectorElement(this, ResourceTable.Graphic_candy);setBackground(vectorElement)
30子元件將拖拽事件傳遞給父元件
安卓:略。
鴻蒙:註冊 setDraggedListener 偵聽,實現 onDragPreAccept 方法,再方法內根據拖拽方向判斷是否需要父元件處理,如果需要則返回 false,否則返回 true。
資源管理
01管理資源
安卓:
AssertManager
鴻蒙:
ResourceManager
02獲取應用的資原始檔 rawFile,並返回 InputStream
安卓:
getResources()AssetManager類
鴻蒙:
ResourceManager resourceManager = getContext().getResourceManager(); RawFileEntry rawFileEntry = resourceManager.getRawFileEntry(jsonFile); Resource resource = null; try { resource = rawFileEntry.openRawFile(); } catch (IOException e) { e.printStackTrace(); }
備註:Resource 是 InputStream 的子類,可以直接作為 InputStream 使用。
03獲取檔案路徑
安卓:
Environment.getExternalStorageDirectory().getAbsolutePath()
鴻蒙:
獲取文件(DIRECTORY_DOCUMENTS)、下載(DIRECTORY_DOWNLOADS)、影片(DIRECTORY_MOVIES)、音樂(DIRECTORY_MUSIC)、圖片(DIRECTORY_PICTURES)GetExternalFilesDir(Environment.DIRECTORY_PICTURES).getAbsolutePath()
訊息&多執行緒
01事件迴圈器
安卓:
android.os.Looper
鴻蒙:
EventRunner.create(true)
備註:有引數且為 true,表示佇列被託管,引數為 false,或無參表示不被託管,需要 eventRunner.run() 呼叫。
02訊息
安卓:
android.os.Message
鴻蒙:
InnerEvent
03休眠
安卓:
android.os.SystemClock.sleep()
鴻蒙:
ohos.miscservices.timeutility.time;Time.sleep(int millesend)
04事件通知延遲訊息
安卓:
Handler.postDelayed(MESSAGE_LOGIN, 5000);
鴻蒙:
Handler.postTask(task, 5000);
05Intent 傳遞引數
安卓:
Intent.putExtra or add Bundle
鴻蒙:
Intent.setParam
06訊息傳送
安卓:Handler handler = new Handler,透過 handlerMsg 發訊息。
鴻蒙:
InnerEvent event1 = InnerEvent.get(eventId1, param, object); myHandler.sendEvent(event1, 0, Priority.IMMEDIATE);
07更新 UI
安卓:
class MyHandle extends Handler{ @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 1: //更新UI的操作 break; default: Break; } } }
鴻蒙:
abilitySlice.getUITaskDispatcher().asyncDispatch(() -> { //更新UI的操作});
圖片處理
01點陣圖資源
安卓:Bitmap。
鴻蒙:PixelMap。
02影象縮放,拉伸到檢視邊界
安卓:
ImageView.ScaleTypeimage.setScaleType(ScaleType.FXY);
鴻蒙:
Image.ScaleModeimage.setScaleMode(Image.ScaleMode.STRETCH);
03List 元件&內容介面卡
安卓:
ListViewextends BaeAdapterViewPage.setAdapter(BaeAdapter);
鴻蒙:
ListContainerextends PageSliderPageSlider.setProvider(PageSlider);
04圖片顯示元件
安卓:
androidx.appcompat.widget.AppCompatImageViewBitmap bitmap = BitmapFactory.decodeResource(context.getResources(),drawableId);Image.setImageBitmap(bitmap);
鴻蒙:
ohos.agp.components.Image
根據實際情況可傳遞其他引數:
ImageSource imageSource = ImageSource.create(file, new ImageSource.SourceOptions());pixelMap = imageSource.createPixelmap(new ImageSource.DecodingOptions());image.setPixelMap(pixelMap);
05圖片填充整個控制元件
安卓:
image.setScaleType(ScaleType.FXY);
鴻蒙:
image.setScaleMode(Image.ScaleMode.STRETCH);
06透過資源 id 獲取點陣圖
安卓:
getBitmapFromDrawable
鴻蒙:
/** * 透過資源ID獲取點陣圖物件 **/ private PixelMap getPixelMap(int resId) { InputStream drawableInputStream = null; try { drawableInputStream = getResourceManager().getResource(resId); ImageSource.SourceOptions sourceOptions = new ImageSource.SourceOptions(); sourceOptions.formatHint = ""image/png""; ImageSource imageSource = ImageSource.create(drawableInputStream, null); ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions(); decodingOptions.desiredSize = new Size(0, 0); decodingOptions.desiredRegion = new Rect(0, 0, 0, 0); decodingOptions.desiredPixelFormat = PixelFormat.ARGB_8888; PixelMap pixelMap = imageSource.createPixelmap(decodingOptions); return pixelMap; } catch (Exception e) { e.printStackTrace(); } finally { try { if (drawableInputStream != null) { drawableInputStream.close(); } } catch (Exception e) { e.printStackTrace(); } } return null; }
07獲取 Gif 圖片幀
安卓:需要自定 frame 類,透過 decoder 獲取。
鴻蒙:
ImageSource.createPixelmap(int index, ImageSource.DecodingOptions opts)
08BMP 點陣圖裁剪
安卓:
Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height)
鴻蒙:
PixelMap.create(PixelMap source, Rect srcRegion, PixelMap.InitializationOptions opts)
影片播放
在影片播放視窗上層增加控制元件。
安卓:略。
鴻蒙:兩種方式。
A.pinToTop 設定 false,保證其他控制元件與 surfaceProvider 在同一 layout 下,並且不能設定背景。
B.增加以下程式碼設定頂部視窗透明:
WindowManager.getInstance().getTopWindow().get().setTransparent(true);
資料庫
資料庫獲取索引。
安卓:
android.database.Cursor;cursor.getString()/cursor.getColumnIndex()
鴻蒙:
ohos.data.resultset
資料結構
01應用程式資料共享
安卓:
context.getContentResolver();resolver.getType(uri)
鴻蒙:
ohos.aafwk.ability.DataAbilityHelper
02JSON 解析
安卓:
import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import org.json.JSONTokener;
鴻蒙:
Gson,fastJson
03物件序列化
安卓:
android.os.Parcel;parcel.readParcelable();parcel.writeParcelable()
鴻蒙:
ohos.utils.parcel
04浮點數矩形,獲取中心點
安卓:
RectF.centerX()
鴻蒙:
RectFloat.getCenter().getPointX()
05資料結構類
安卓:
LongSparseArraySparseArrayCompat
鴻蒙:使用 HashMap<Long,Ojbect> 和 HashMap<Integer,Ojbect> 替代。
備註:記憶體使用和查詢效能會有影響。
06浮點數矩形
安卓:
RectF
鴻蒙:
RectFloat
07浮點座標
安卓:
PointF
鴻蒙:可使用 Point。
對話方塊
01對話方塊銷燬
安卓:
mDialog.dismiss()
鴻蒙:
mDialog.destroy();
02對話方塊中載入佈局
安卓:
mDialog.setContentView(ViewGroup dialogView)
鴻蒙:
安卓:
mDialog.setCancelable(mPickerOptions.cancelable)
鴻蒙:
mDialog.setDialogListener(new BaseDialog.DialogListener() { @Override public boolean isTouchOutside() { mDialog.destroy(); dialogView.getComponentParent().removeComponent(dialogView); return true; } });
備註:鴻蒙對話方塊銷燬之後需移除對話方塊中載入的佈局,否則再次載入會報錯。
動畫
01旋轉動畫
安卓:
android.view.animation.RotateAnimation
鴻蒙:
ohos.agp.animation.AnimatorProperty
02值動畫及相關回調
安卓:
android.animation.ValueAnimatorValueAnimator.AnimatorUpdateListenerAnimator.AnimatorListenerAnimator.AnimatorPauseListener
鴻蒙:
ohos.agp.animation.AnimatorValueAnimatorValue.ValueUpdateListenerAnimator.StateChangedListenerAnimator.LoopedListener
備註:啟動動畫時,AnimatorValue 必須作為類的成員變數,而不能時函式區域性變數,否則動畫不會啟動。
03線性插值器
安卓:
LinearInterpolator
鴻蒙:自己寫一個。public interface Interpolator { float getInterpolation(float input);}public class LinearInterpolator implements Interpolator { public LinearInterpolator() { } public LinearInterpolator(Context context, AttrSet attrs) { } public float getInterpolation(float input) { return input; }}
04設定動畫迴圈次數
安卓:
animation.setRepeatCount(Animation.INFINITE)
鴻蒙:
animator.setLoopedCount(Animator.INFINITE)
儲存
獲取儲存根路徑。
安卓:
Environment.getExternalStorageDirectory().getAbsolutePath();
鴻蒙:
System.getProperty("user.dir")
Canvas 繪圖
01繪製圓弧
安卓:
Android canvas.drawArc()
鴻蒙:
ohos.agp.render; class Arc
02繪製圓形的兩種方式
安卓:
canvas.drawCircle(float x, float y, float radius, Paint paint)
鴻蒙:
A.canvas.drawPixelMapHolderRoundRectShape(PixelMapHolder holder, RectFloat rectSrc, RectFloat rectDst, float radiusX, float radiusY) B.canvas.drawCircle(float x, float y, float radius, Paint paint)
03繪製文字的方法
安卓:
drawText (String text, float x, float y, Paint paint)
鴻蒙:
drawText(Paint paint, String text, float x, float y)
04獲取 text 的寬度
安卓:
text.getWidth();
鴻蒙:
Paint paint = new Paint();paint.setTextSize(text.getTextSize());float childWidth = paint.measureText(text.getText());
作者: 軟通田可輝
原文連結:https://mp.weixin.qq.com/s/SrPaQuxiYJSQqPsQJMkDpA