主頁 > 移動端開發 > 安卓學習日志 Day14 — 偏好設定

安卓學習日志 Day14 — 偏好設定

2021-01-28 11:01:54 移動端開發

概述

本文將了解 如何通過將設定螢屏添加到應用來自定義 應用中所顯示的地震串列,用戶可以選擇應顯示地震的最小震級 并可以更改是 按震級還是按時間來顯示地震,要將此 功能添加到應用,需要添加新設定活動,然后使用 用戶的偏好來更改用于 查詢地震的 URL,

追求“驚艷”是 Android 的基本原則之一, 這通常意味著每個用戶都需要 適合自己和滿足自身偏好的略微不同的體驗,因此,我們需要 通過一種方法使用戶能夠調整應用中的偏好,并且使系統記住 用戶選定的偏好,例如,你詢問用戶感興趣的 最小震級,而用戶回答為 “5”,則每次獲取該用戶的地震資訊時, 即使用戶關閉應用又重新將其打開. 仍然只需獲取震級高于 5 的地震,即便用戶關閉 手機,隨后又再次開機依然如此!

在用戶設備上存盤資料(通常指資料持久化) 是一個龐大的主題,同時也將成為整個 下一學習階段的主題,

但目前,Android 的設計者希望存盤少量資料 以追蹤客戶偏好, 因此通過 Android 組件來完成此功能,

SharedPreferences

偏好其實就是與簡單型別、字串或字串集 相關聯的字串鍵,即使應用已關閉,或者電話已關機, Android 也會保留該資料, Android 提供 SharedPreferences 類用于直接獲取和 設定偏好,SharedPreferences 可以處理 將偏好資料讀寫到 設備上持久化存盤(檔案)的所有詳細資訊,

除了存盤偏好,還需要提供一種方法以使 用戶通過用戶界面來編輯應用中的偏好, 對于數字偏好,需要允許用戶鍵入 數字,對于應從串列中選擇的偏好,則需要 顯示選項串列,并允許用戶從中選擇一個選項等,

雖然我們自己可以設定此類活動,但是 Android 提供 名為 PreferenceFragment 的類,該類可以顯示 UI 小工具 (Preference 物件)的串列,用于輕松編輯各種 偏好,

為防止你錯過這些內容,術語 Fragment 是最新的,讓我們來談談它 的含義吧,

因為很多 Android 活動可以從 嵌入偏好編輯小工具集獲益,所以 Android 構架團隊要盡可能簡化此任務,

想象一下如果能夠通過可置于活動布局中的 假定“PreferencesView”來完成此操作, 但是,我們需要通過一種方法使“PreferencesView”比簡單視圖更為智能, 而同時又不希望將其變成完全成熟的 活動,它只需作為活動的一小部分,例如, 活動的 Fragment,

Fragment 的行為很像相應活動中的 微型活動,通過引入 Fragment 可以實作適用于 大螢屏平板電腦和其他 Android 設備的 更加靈活的布局,

Fragment 可以在多個活動內重用,且一個活動 可以使用多個 Fragment,對于平板電腦 UI, 常用的模式是同時使用兩個 Fragment,

現在,無需了解更多關于 Fragment 的內容, 在本中,不會講述與多個 Fragment 相關的復雜內容, 我們將要做的是 在 SettingsActivity 內使用 PreferenceFragment 來顯示用戶可以編輯的 偏好串列,

有關 Fragment 的更多高級內容,請參閱創建單窗格和多窗格布局以及 構建靈活的 UI,

構建偏好螢屏

添加 SettingsActivity 并將其啟動,然后將選單 添加到 EarthquakeActivity!

第一步,向 res/values/strings.xml 檔案添加一些字串,

在 strings.xml 中:

<!-- Settings Menu Item [CHAR LIMIT=NONE] -->
<string name="settings_menu_item">Settings</string>
<!-- Settings Activity Title [CHAR LIMIT=NONE] -->
<string name="settings_title">Earthquake Settings</string>

下一步,將創建 SettingsActivity 類,

在 SettingsActivity.java 中:

package com.example.quakereport;

import android.os.Bundle;
import android.preference.PreferenceFragment;

import androidx.appcompat.app.AppCompatActivity;

public class SettingsActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_settings);
    }

    public static class EarthquakePreferenceFragment extends PreferenceFragment {

    }
}

在 res/layout/settings_activity.xml 中定義設定活動的布局:

在 settings_activity.xml 中:

<fragment
    android:name="com.example.android.quakereport.SettingsActivity$EarthquakePreferenceFragment"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.quakereport.SettingsActivity">
</fragment>

當然,需要 在標簽內的 AndroidManifest.xml 中宣告新活動:

在 AndroidManifest.xml 中:

<activity
    android:name=".SettingsActivity"
    android:label="@string/settings_title">
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value="com.example.quakereport.EarthquakeActivity"/>
</activity>

選單

如果將一個較大的 SETTINGS 按鈕放置在地震串列上方或下方, 則會使 EarthquakeActivity 顯得非常雜亂,將該按鈕放置在 位于 EarthquakeActivity 頂部的應用欄內更為合適,

活動可以使用選單資源檔案,并在 應用欄中顯示選單,因此,接下來將在新選單資源檔案中 定義選單項:

在 res/menu/main.xml 中:

     <menu xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:app="http://schemas.android.com/apk/res-auto"
         xmlns:tools="http://schemas.android.com/tools"
         tools:context="com.example.android.quakereport.EarthquakeActivity">
         <item
             android:id="@+id/action_settings"
             android:title="@string/settings_menu_item" 
             android:icon="@drawable/ic_filter"
             android:orderInCategory="1"
             app:showAsAction="ifRoom" />
     </menu>

覆寫 EarthquakeActivity.java 中的一些方法以使用 選單,然后在用戶單擊選單項時作出回應:

在 EarthquakeActivity.java 中:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        Intent settingsIntent = new Intent(this, SettingsActivity.class);
        startActivity(settingsIntent);
        return true;
    }
    return super.onOptionsItemSelected(item);
}

現在,我們已經擁有了選單,其中“Settings”項可以打開(現在是空白的) SettingsActivity!

更改完成前后的差異

最小震級偏好

啟動并運行 SettingsActivity 后,將添加 可以編輯的偏好!

目前,我們已經創建應用,僅顯示 震級等于或高于 6.0 的 10 個最近地震( 通過硬編碼 HTTP 請求以從 URL http://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&eventtype=earthquake&orderby=time&minmag=6&limit=10 獲取資料), 這看起來有些任意,因為應用的其余部分 可以在技術上處理任何地震串列的顯示,因此, 將允許用戶修改應用 將顯示的最小震級,

首先,將向資源檔案再添加幾個字串,

在 strings.xml 中:

  <!-- Strings For Minimum Magnitude Preference [CHAR LIMIT=30] -->
<string name="settings_min_magnitude_label">Minimum Magnitude</string>
<string name="settings_min_magnitude_key" translatable="false">min_magnitude</string>
<string name="settings_min_magnitude_default" translatable="false">6</string>

下一步,需要創建資源,該資源可以定義 螢屏應該顯示的偏好編輯小工具的型別,在 res/xml 目錄中創建 settings_main.xml 檔案,該檔案 內容如下:

在 res/xml/settings_main.xml 中:

<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:title="@string/settings_title">

    <EditTextPreference
        android:defaultValue="@string/settings_min_magnitude_default"
        android:inputType="numberDecimal"
        android:key="@string/settings_min_magnitude_key"
        android:selectAllOnFocus="true"
        android:title="@string/settings_min_magnitude_label" />

</PreferenceScreen>

最后,在 SettingsActivity 中,覆寫 EarthquakePreferenceFragment 內部類中的 onCreate() 方法,以使用以前定義的 settings_main XML 資源,

在 SettingsActivity.java 中:

 package com.example.android.quakereport;

 import android.os.Bundle;
 import android.preference.PreferenceFragment;
 import android.support.v7.app.AppCompatActivity;

 public class SettingsActivity extends AppCompatActivity {

     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.settings_activity);
     }

     public static class EarthquakePreferenceFragment extends PreferenceFragment {

         @Override
         public void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             addPreferencesFromResource(R.xml.settings_main);
         }
     }
 }

現在,Settings UI 應該包含用于設定 最小震級的單個偏好(代碼更改前后對比):

根據用戶偏好構造 URL

目前,已經使用硬編碼固定 URL 請求地震, 但是,我們需要將最小震級偏好作為查詢引數插入到 URL 中,雖然可以通過 一些復雜的字串串聯來實作該功能,但是使用 Uri.Builder 類是一種更好的方法,

等一下,再問一次什么是 URI?URI 即統一資源識別符號,是 更常用的 URL,URL 常常指向計算機網路 上的資源,而 URI 可以識別 范圍更大的事物(從檔案和郵箱到物理 物件,如書),

由于 URL 是 URI 的子集,因此 Android 提供 方法來操縱 URI 是非常有意義的,因為這些 URI 將 同樣適用于 URL,

首先,將 EarthquakeActivity 類中 USGS_REQUEST_URL 常量的值修改為 基準 URI,然后,使用 UriBuilder.appendQueryParameter() 方法將其他引數添加到 URI(例如,JSON 回應格式、已請求 10 個地震、 最小震級值以及排序順序),

在 EarthquakeActivity.java 中:

 private static final String USGS_REQUEST_URL = "http://earthquake.usgs.gov/fdsnws/event/1/query";

然后替換 onCreateLoader() 方法的主體以讀取 最小震級的用戶最新偏好并使用其偏好構造 相應 URI,然后針對 該 URI 創建新 Loader,

在 EarthquakeActivity.java 中:

 @Override
 public Loader<List<Earthquake>> onCreateLoader(int i, Bundle bundle) {

     SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
     String minMagnitude = sharedPrefs.getString(
                 getString(R.string.settings_min_magnitude_key),
                 getString(R.string.settings_min_magnitude_default));
     Uri baseUri = Uri.parse(USGS_REQUEST_URL);
     Uri.Builder uriBuilder = baseUri.buildUpon();

     uriBuilder.appendQueryParameter("format", "geojson");
     uriBuilder.appendQueryParameter("limit", "10");
     uriBuilder.appendQueryParameter("minmag", minMagnitude);
     uriBuilder.appendQueryParameter("orderby", "time");

     return new EarthquakeLoader(this, uriBuilder.toString());
 }

現在已經將最小震級偏好插入到查詢 URL 中! 從 UI 的 SettingsActivity 中,將最小震級 設定為較小的值,然后查看 世界范圍內發生的所有小地震,

更改完成前后的差異,

偏好摘要

對于用戶而言,通過單擊 最小震級偏好來查看其當前設定 并不是一種美妙的體驗,

更好的方法是打開 Setting Activity 即可 查看偏好名稱下方的偏好值, 如果對其進行更改,可以看到摘要將立即更新,

這對于偏好更改后應用能夠立即知曉非常有用, 特別是偏好更改應對 UI 產生某些可見影響,

要實作該功能,當偏好發生更改時,PreferenceFragment 可以實作 OnPreferenceChangeListener 介面 以獲取通知,然后,當用戶更改單個偏好 并進行保存時,將使用已更改偏好的關鍵字來呼叫 onPreferenceChange() 方法,請注意,此方法 將回傳布林值,可防止通過回傳 false 來 更改建議的偏好設定,

首先宣告 EarthquakePreferenceFragment 類應 實作 OnPreferenceChangeListener 介面,然后覆寫 onPreferenceChange() 方法,此方法中的代碼 會在偏好更改后更新已顯示的偏好摘要,

在 SettingsActivity 中,在 EarthquakePreferenceFragment 類中:

  public static class EarthquakePreferenceFragment extends PreferenceFragment implements Preference.OnPreferenceChangeListener {

         @Override
         public void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             addPreferencesFromResource(R.xml.settings_main);
         }

         @Override
         public boolean onPreferenceChange(Preference preference, Object value) {
             String stringValue = value.toString();
             preference.setSummary(stringValue);
             return true;
         }
     }

但是,在啟動設定活動后, 仍需要更新偏好摘要,如果給定偏好的鍵,可以 使用 PreferenceFragment 的 findPreference() 方法來獲取偏好 物件,然后使用 bindPreferenceSummaryToValue() 幫助程式方法來設定偏好,

在 EarthquakePreferenceFragment 中:

 @Override
 public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     addPreferencesFromResource(R.xml.settings_main);

     Preference minMagnitude = findPreference(getString(R.string.settings_min_magnitude_key));
     bindPreferenceSummaryToValue(minMagnitude);
 }

現在需要定義 bindPreferenceSummaryToValue() 幫助程式方法 來設定當前 EarhtquakePreferenceFragment 實體作為 每個偏好上的偵聽程式,還將讀取 設備上 SharedPreferences 中存盤的偏好當前值,然后在 偏好摘要中進行顯示(以便用戶能夠查看 偏好的當前值),

在 EarthquakePreferenceFragment 中:

 private void bindPreferenceSummaryToValue(Preference preference) {
     preference.setOnPreferenceChangeListener(this);
     SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(preference.getContext());
     String preferenceString = preferences.getString(preference.getKey(), "");
     onPreferenceChange(preference, preferenceString);
 }

更改后,整個 SettingsActivity 檔案 將如下所示:

在 SettingsActivity.java 中:

 package com.example.android.quakereport;

 import android.content.SharedPreferences;
 import android.os.Bundle;
 import android.preference.Preference;
 import android.preference.PreferenceFragment;
 import android.preference.PreferenceManager;
 import android.support.v7.app.AppCompatActivity;

 public class SettingsActivity extends AppCompatActivity {

     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.settings_activity);
     }

     public static class EarthquakePreferenceFragment extends PreferenceFragment implements Preference.OnPreferenceChangeListener {

         @Override
         public void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             addPreferencesFromResource(R.xml.settings_main);

             Preference minMagnitude = findPreference(getString(R.string.settings_min_magnitude_key));
             bindPreferenceSummaryToValue(minMagnitude);
         }

         @Override
         public boolean onPreferenceChange(Preference preference, Object value) {
             String stringValue = value.toString();
             preference.setSummary(stringValue);
             return true;
         }

         private void bindPreferenceSummaryToValue(Preference preference) {
             preference.setOnPreferenceChangeListener(this);
             SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(preference.getContext());
             String preferenceString = preferences.getString(preference.getKey(), "");
             onPreferenceChange(preference, preferenceString);
         }
     }
 }

更改完成前后的差異

下面是運行截圖:

地震串列的排序偏好

我們將再添加一個偏好選項,有時,用戶要了解 震級最大的地震,而有時用戶卻要 了解最近發生的地震,我們可以 使用 ListPreference 輕松實作用戶的要求,首先,在字串資源檔案中定義 更多字串,

在 strings.xml 中:

 <!-- Strings For Order-By Preference [CHAR LIMIT=30] -->
 <string name="settings_order_by_label">Order By</string>
 <string name="settings_order_by_key" translatable="false">order_by</string>
 <string name="settings_order_by_default" translatable="false">@string/settings_order_by_magnitude_value</string>

 <!-- Label for order-by magnitude option [CHAR LIMIT=20] -->
 <string name="settings_order_by_magnitude_label">Magnitude</string>
 <string name="settings_order_by_magnitude_value" translatable="false">magnitude</string>

 <!-- Label for order-by most recent option [CHAR LIMIT=20] -->
 <string name="settings_order_by_most_recent_label">Most Recent</string>
 <string name="settings_order_by_most_recent_value" translatable="false">time</string>

下一步,我們將通過創建 new res/values/arrays.xml 檔案將這些字串打包到字串陣列中,

在 res/values/arrays.xml 中:

 <?xml version="1.0" encoding="utf-8"?>
 <resources>
     <string-array name="settings_order_by_labels">
         <item>@string/settings_order_by_magnitude_label</item>
         <item>@string/settings_order_by_most_recent_label</item>
     </string-array>

     <string-array name="settings_order_by_values">
         <item>@string/settings_order_by_magnitude_value</item>
         <item>@string/settings_order_by_most_recent_value</item>
     </string-array>
 </resources>

然后將 ListPreference 添加到 res/xml/settings_main.xml 檔案中,整個 XML 檔案應包含以下內容:

在 res/xml/settings_main.xml 中:

 <?xml version="1.0" encoding="utf-8"?>
 <PreferenceScreen
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:title="@string/settings_title">

     <ListPreference
         android:defaultValue="@string/settings_order_by_default"
         android:entries="@array/settings_order_by_labels"
         android:entryValues="@array/settings_order_by_values"
         android:key="@string/settings_order_by_key"
         android:title="@string/settings_order_by_label" />

     <EditTextPreference
         android:defaultValue="@string/settings_min_magnitude_default"
         android:inputType="numberDecimal"
         android:key="@string/settings_min_magnitude_key"
         android:selectAllOnFocus="true"
         android:title="@string/settings_min_magnitude_label" />

 </PreferenceScreen>

然后,構建用于創建 HTTP 請求的 URI 時,需要查找用戶首選的排序順序,從 SharedPreferences 進行讀取, 然后查看與鍵相關的值: getString(R.string.settings_order_by_key),構建 URI 和 附加查詢引數時,將使用用戶的偏好 (存盤在 orderBy 變數中), 而非將“orderby”引數硬編碼為“time”,

在 EarthquakeActivity.java 中:

     @Override
     public Loader<List<Earthquake>> onCreateLoader(int i, Bundle bundle) {

         SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
         String minMagnitude = sharedPrefs.getString(
                 getString(R.string.settings_min_magnitude_key),
                 getString(R.string.settings_min_magnitude_default));

         String orderBy = sharedPrefs.getString(
                 getString(R.string.settings_order_by_key),
                 getString(R.string.settings_order_by_default)
         );

         Uri baseUri = Uri.parse(USGS_REQUEST_URL);
         Uri.Builder uriBuilder = baseUri.buildUpon();

         uriBuilder.appendQueryParameter("format", "geojson");
         uriBuilder.appendQueryParameter("limit", "10");
         uriBuilder.appendQueryParameter("minmag", minMagnitude);
         uriBuilder.appendQueryParameter("orderby", orderBy);

         return new EarthquakeLoader(this, uriBuilder.toString());
     }

最后,我們將在 EarthquakePreferenceFragment 中添加其他邏輯,以使其能夠識別新的 ListPreference,該操作類似針對 EditTextPreference 的操作,在 Fragment 的 onCreate() 方法中,根據偏好物件的鍵來查找“order by”偏好 物件,然后呼叫此偏好物件的 bindPreferenceSummaryToValue() 幫助程式方法, 該方法可將此 Fragment 設定為 OnPreferenceChangeListener 并 更新摘要,以使其顯示 SharedPreferences 中存盤的當前值,

在 SettingsActivity.java 中,在 EarthquakePreferenceFragment 類中:

 @Override
 public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     addPreferencesFromResource(R.xml.settings_main);

      Preference minMagnitude = findPreference(getString(R.string.settings_min_magnitude_key));
      bindPreferenceSummaryToValue(minMagnitude);

      Preference orderBy = findPreference(getString(R.string.settings_order_by_key));
      bindPreferenceSummaryToValue(orderBy);
 }

由于這是 EarthquakePreferenceFragment 遇到的第一個 first ListPreference, 請更新 EarthquakePreferenceFragment 中的 toonPreferenceChange() 方法,以 正確更新 ListPreference 的摘要(使用標記, 而非鍵),

在 SettingsActivity.java 中,在 EarthquakePreferenceFragment 類中:

 @Override
 public boolean onPreferenceChange(Preference preference, Object value) {
     String stringValue = value.toString();
     if (preference instanceof ListPreference) {
         ListPreference listPreference = (ListPreference) preference;
         int prefIndex = listPreference.findIndexOfValue(stringValue);
         if (prefIndex >= 0) {
             CharSequence[] labels = listPreference.getEntries();
             preference.setSummary(labels[prefIndex]);
         }
     } else {
         preference.setSummary(stringValue);
     }
     return true;
 }

我們已完成一個簡單的設定活動!代碼如下 所示:

在 SettingsActivity.java 中:

 package com.example.android.quakereport;

 import android.content.SharedPreferences;
 import android.os.Bundle;
 import android.preference.ListPreference;
 import android.preference.Preference;
 import android.preference.PreferenceFragment;
 import android.preference.PreferenceManager;
 import android.support.v7.app.AppCompatActivity;

 public class SettingsActivity extends AppCompatActivity {

     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.settings_activity);
     }

     public static class EarthquakePreferenceFragment extends PreferenceFragment implements Preference.OnPreferenceChangeListener {

         @Override
         public void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             addPreferencesFromResource(R.xml.settings_main);

             Preference minMagnitude = findPreference(getString(R.string.settings_min_magnitude_key));
             bindPreferenceSummaryToValue(minMagnitude);

             Preference orderBy = findPreference(getString(R.string.settings_order_by_key));
             bindPreferenceSummaryToValue(orderBy);
         }

         @Override
         public boolean onPreferenceChange(Preference preference, Object value) {
             String stringValue = value.toString();
             if (preference instanceof ListPreference) {
                 ListPreference listPreference = (ListPreference) preference;
                 int prefIndex = listPreference.findIndexOfValue(stringValue);
                 if (prefIndex >= 0) {
                     CharSequence[] labels = listPreference.getEntries();
                     preference.setSummary(labels[prefIndex]);
                 }
             } else {
                 preference.setSummary(stringValue);
             }
             return true;
         }

         private void bindPreferenceSummaryToValue(Preference preference) {
             preference.setOnPreferenceChangeListener(this);
             SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(preference.getContext());
             String preferenceString = preferences.getString(preference.getKey(), "");
             onPreferenceChange(preference, preferenceString);
         }
     }
 }

運行應用時,請轉至設定,然后基于 震級或時間修改排序順序,然后查看地震串列的變化!

練習完成前后的差異

錄屏演示:

https://www.bilibili.com/video/BV1Ky4y1p71z?p=3

<iframe id="vQ54oquX-1611760577029" src="https://player.bilibili.com/player.html?aid=801276333&page=3" allowfullscreen="true" data-mediaembed="bilibili"></iframe>

QuakeReport — 應用測驗

參考

有關偏好的 材料設計指南

Using Shared Preferences

Save key-value data | Android Developers

SharedPreferences | Android Developers

PreferenceFragment | Android Developers

Settings with PreferenceFragment | CodePath Android Cliffnotes

Using PreferenceFragmentCompat to Store User Preferences

Preference Fragment · Developing for Android

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/253503.html

標籤:其他

上一篇:網路資料原來是這么傳輸的(結合影片決議)

下一篇:android如何實作qq登陸和qq分享,2021超詳細mob平臺圖解教程?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more