偏好设置SharedPerferences、根据偏好构建查询url、使用下拉刷新SwipeRefreshLayout.OnRefreshListener接口

14 篇文章 0 订阅
这篇博客详细介绍了如何在Android应用中实现偏好设置,包括创建SettingsActivity和EarthquakePreferenceFragment,使用SharedPreferences存储用户偏好。同时,讲解了如何根据用户偏好构建URL,并利用Uri.Builder进行高效操作。此外,还探讨了集成SwipeRefreshLayout实现下拉刷新功能,包括OnRefreshListener接口的使用和集成到ListView中。
摘要由CSDN通过智能技术生成

一,Android应用栏右上角的设置按钮(菜单项),点击后进入一个新的设置界面

首先在Earthquake应用中的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/settting_menu_item"
	        android:icon="@mipmap/ic_launcher"
	        android:orderInCategory="1"
	        app:showAsAction="ifRoom"/>
	</menu>

更新strings.xml在res/values/strings.xml文件中添加一些字符串,更新后的strings.xml

<resources>
    <string name="app_name">Earthquake Report</string>
    <string name="near_the">Near the</string>
    <string name="settting_menu_item">Setting</string>
    <string name="settings_title">Earthquake Setting</string>
    <string name="setting_min_magnitude_label">Choose Minimum Magnitude</string>
    <string name="setting_min_magnitude_key" translatable="false">min_magnitude</string>
    <string name="setting_min_magnitude_default" translatable="false">6</string>
    <string name="setting_location">Location</string>
    <string name="setting_location_default">world</string>
    <string name="setting_date">Date Setting</string>
    <string name="setting_date_default">1</string>
</resources>

覆盖 EarthquakeActivity.java 中的onCreateOptionMenu方法和onOptionItemSelected方法以使用 菜单,然后在用户单击菜单项时作出响应,进入一个新的设置界面

@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);
}
添加设置界面:创建SettingsActivity类,创建EarthuquakePreferenceFragment内部类继承自PreferenceFragment来设置偏好
public class SettingsActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_settings);
    }
    //创建内部类EarthquakePreference继承自PreferenceFragment,用于设置偏好
     public static class EarthquakePreferenceFragment extends PreferenceFragment {

	}
}

res/layout/activity_settings.xm中定义设置活动的布局:
在activity_settings.xml中添加:

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

</fragment>

其中android:name属性用于fragment布局关联到Fragment

在AndroidManifest.xml中声明新活动

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.quakereport">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
 		...
        
        <activity
            android:name=".SettingsActivity"
            android:label="@string/settings_title">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="com.example.android.quakereport.EarthquakeActivity" />
                
        </activity>
    </application>

</manifest>
SharedPreferences是一种轻量级的存储工具,采用的是Key-Value的键值对的存储结构,SharedPreferences的存储介质是符合XML规范的配置文件。

偏好设置数据在res/xml/settings_main.xml中存储。
在settings_main.xml中添加

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

    <EditTextPreference
        android:defaultValue="@string/setting_min_magnitude_default"
        android:inputType="numberDecimal"
        android:key="@string/setting_min_magnitude_key"
        android:selectAllOnFocus="true"
        android:title="@string/setting_min_magnitude_label" />

    <ListPreference
        android:title="@string/setting_location"
        android:dialogTitle="@string/setting_location"
        android:entries="@array/location"
        android:entryValues="@array/location_value"
        android:key="@string/setting_location"
        android:defaultValue="@string/setting_location_default">
    </ListPreference>

    <ListPreference
        android:title="@string/setting_date"
        android:dialogTitle="@string/setting_date"
        android:key="@string/setting_date"
        android:entries="@array/date"
        android:entryValues="@array/date_value"
        android:defaultValue="@string/setting_date_default">
    </ListPreference>
</PreferenceScreen>

在SettingActivity中,覆盖 EarthquakePreferenceFragment 内部类中的 onCreate() 方法,以使用新定义的 settings_main XML 资源。

 public class SettingsActivity extends AppCompatActivity {

	...

     public static class EarthquakePreferenceFragment extends PreferenceFragment {

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

偏好设置中的ListPreference的使用:列表数据存在res/values/arrays.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="location">
        <item>China</item>
        <item>US</item>
        <item>Europe</item>
        <item>Allover the World</item>
    </string-array>

    <string-array name="location_value">
        <item>30.67,104.06</item>
        <item>39.04,-97.95</item>
        <item>50.40,23.14</item>
        <item>world</item>
    </string-array>

    <string-array name="date">
        <item>1 day before</item>
        <item>2 day before</item>
        <item>3 day before</item>
        <item>4 day before</item>
        <item>5 day before</item>
    </string-array>

    <string-array name="date_value">
        <item>1</item>
        <item>2</item>
        <item>3</item>
        <item>4</item>
        <item>5</item>
    </string-array>
</resources>

二,根据用户偏好构建构造所需URL(该方法可以之后用到别的应用中)。

在这之前,我们已经使用硬编码固定 URL 请求地震。 但是,我们需要将最小震级偏好作为查询参数插入到 URL 中。虽然可以通过 一些复杂的字符串串联来实现该功能,但是使用 Uri.Builder 类是一种更好的方法。

再问一次什么是 URI?URI 即统一资源标识符,是 更常用的 URL。URL 常常指向计算机网络 上的资源而 URI 可以识别 范围更大的事物(从文件和邮箱到物理 对象,如书)

由于 URL 是 URI 的子集因此 Android 提供 方法来操纵 URI 是非常有意义的,因为这些 URI 将 同样适用于 URL。

在EarthquakeActivity中添加以下方法updateUrl方法,该方法可以之后用到别的应用中

private void updateUrl(){

        USGS_REQUEST_URL = "https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=";


        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        //获取最小震级和之前天数对应偏好设置的值
        String minMagnitude = sharedPreferences.getString(getString(R.string.setting_min_magnitude_key), getString(R.string.setting_min_magnitude_default));
        String before_day = sharedPreferences.getString(getString(R.string.setting_date), getString(R.string.setting_date_default));

        //add the date,获取之前某段时间的方法
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DATE, - Integer.parseInt(before_day));
        Date day = calendar.getTime();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String starttime = format.format(day);
        USGS_REQUEST_URL += starttime;

        //先将USGS_REQUEST_URL 常量的值修改为 基准 URI
        Uri baseUri = Uri.parse(USGS_REQUEST_URL);
        //在此baseUri之上进行添加,
        Uri.Builder uriBuilder = baseUri.buildUpon();
        //添加最小震级参数
        uriBuilder.appendQueryParameter("minmag", minMagnitude);
        //获取位置偏好的参数
        String location = sharedPreferences.getString(getString(R.string.setting_location),"world");

        //如果是位置偏好是世界范围的则不添加位置偏好到url中
        if (!location.equals("world")){
            String[] part = location.split(",");
            String latitude = part[0];
            String longitude = part[1];
            String maxradiuskm = "800";
            uriBuilder.appendQueryParameter("latitude", latitude);
            uriBuilder.appendQueryParameter("longitude", longitude);
            uriBuilder.appendQueryParameter("maxradiuskm", maxradiuskm);
        }
        
        USGS_REQUEST_URL = uriBuilder.toString();
    }

三,使用下拉刷新SwipeRefreshLayout.OnRefreshListener接口

在EarthquakeActivity.java中添加接口,并且重写OnRefresh()方法,

public class EarthquakeActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener {
	...
	swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);
    //设置刷新监听器
    swipeRefreshLayout.setOnRefreshListener(this);
    //设置进度圆圈的背景颜色
    swipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary);
    
	@Override
    public void onRefresh() {
        //update USGS_REQUEST_URL
        updateUrl();
        EarthquakeActivity.EarthquakeAsyncTask earthquakeAsyncTask = new EarthquakeActivity.EarthquakeAsyncTask();
        //AsyncTask.execute方法会将参数传到doInBackground中执行
        earthquakeAsyncTask.execute(USGS_REQUEST_URL);
    }
    ...
}

在activity_earthquake.xml中添加SwipeRefreshLayout节点,该节点下面只能有一个直接子视图,且这个视图必须是可以滚动的,例如ListView

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v4.widget.SwipeRefreshLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/swipe_refresh_layout">
        
        <ListView
            android:id="@+id/list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
        </ListView>
    </android.support.v4.widget.SwipeRefreshLayout>
    
    <TextView
        android:id="@+id/empty_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="No earthquake found"
        android:layout_centerInParent="true" />

    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/progress_bar"
        android:layout_centerInParent="true"/>
    
</RelativeLayout>

在EarthquakeActivty.java内部类EarthquakeAsyncTask中的onPostExecute()添加收到数据后结束刷新。

		...
        @Override
        protected void onPostExecute(final ArrayList<Earthquake> earthquakes) {
            //收到数据后结束下拉刷新动作
            swipeRefreshLayout.setRefreshing(false);

            ...
            if (earthquakes != null && !earthquakes.isEmpty()) {


               ...
                //if the earthquake array list is not null then set the progressBar divisible
                progressBar.setVisibility(View.GONE);
                emptyView.setVisibility(View.INVISIBLE);


            } else {
                //收到数据后结束下拉刷新动作
                swipeRefreshLayout.setRefreshing(false);

                // Set the adapter on the {@link ListView}
                // so the list can be populated in the user interface
                earthquakeListView.setAdapter(adapter);
                //if the earthquake array list null then set the emptyView visible and progressBar divisible
                emptyView.setVisibility(View.VISIBLE);
                progressBar.setVisibility(View.GONE);

            }

        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值