davdroid

2016-09-22  本文已影响276人  81bad73e9053

davdrod学习记录

1.Preference的使用

<?xml version="1.0" encoding="utf-8"?><!--  ~ Copyright (c) 2013 – 2015 Ricki Hirner (bitfire web engineering).  ~ All rights reserved. This program and the accompanying materials  ~ are made available under the terms of the GNU Public License v3.0  ~ which accompanies this distribution, and is available at  ~ http://www.gnu.org/licenses/gpl.html  --><PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">    <PreferenceCategory android:title="@string/settings_authentication">        <EditTextPreference            android:key="username"            android:title="@string/settings_username"            android:persistent="false"            android:dialogTitle="@string/settings_enter_username" />        <EditTextPreference            android:key="password"            android:title="@string/settings_password"            android:persistent="false"            android:inputType="textPassword"            android:summary="@string/settings_password_summary"            android:dialogTitle="@string/settings_enter_password" />    </PreferenceCategory>    <PreferenceCategory android:title="@string/settings_sync">        <ListPreference            android:key="sync_interval_contacts"            android:persistent="false"            android:title="@string/settings_sync_interval_contacts"            android:entries="@array/settings_sync_interval_names"            android:entryValues="@array/settings_sync_interval_seconds" />        <ListPreference            android:key="sync_interval_calendars"            android:persistent="false"            android:title="@string/settings_sync_interval_calendars"            android:entries="@array/settings_sync_interval_names"            android:entryValues="@array/settings_sync_interval_seconds" />        <ListPreference            android:key="sync_interval_tasks"            android:persistent="false"            android:title="@string/settings_sync_interval_tasks"            android:entries="@array/settings_sync_interval_names"            android:entryValues="@array/settings_sync_interval_seconds" />        <SwitchPreferenceCompat            android:key="sync_wifi_only"            android:persistent="false"            android:title="@string/settings_sync_wifi_only"            android:summaryOn="@string/settings_sync_wifi_only_on"            android:summaryOff="@string/settings_sync_wifi_only_off"            />        <EditTextPreference            android:key="sync_wifi_only_ssid"            android:dependency="sync_wifi_only"            android:persistent="false"            android:title="@string/settings_sync_wifi_only_ssid"            android:dialogMessage="@string/settings_sync_wifi_only_ssid_message"/>    </PreferenceCategory>    <PreferenceCategory android:title="@string/settings_carddav">        <ListPreference            android:key="contact_group_method"            android:persistent="false"            android:title="@string/settings_contact_group_method"            android:entries="@array/settings_contact_group_method_entries"            android:entryValues="@array/settings_contact_group_method_values"/>        <SwitchPreferenceCompat            android:key="vcard_rfc6868"            android:persistent="false"            android:title="@string/settings_rfc6868_for_vcards"            android:summaryOn="@string/settings_rfc6868_for_vcards_on"            android:summaryOff="@string/settings_rfc6868_for_vcards_off"/>    </PreferenceCategory>    <PreferenceCategory android:title="@string/settings_caldav">        <EditTextPreference            android:key="time_range_past_days"            android:persistent="false"            android:title="@string/settings_sync_time_range_past"            android:dialogMessage="@string/settings_sync_time_range_past_message"            android:inputType="number"/>        <SwitchPreferenceCompat            android:key="manage_calendar_colors"            android:persistent="false"            android:title="@string/settings_manage_calendar_colors"            android:summaryOn="@string/settings_manage_calendar_colors_on"            android:summaryOff="@string/settings_manage_calendar_colors_off"/>    </PreferenceCategory></PreferenceScreen>

public class AccountSettingsActivity extends AppCompatActivity {    public final static String EXTRA_ACCOUNT = "account";    private Account account;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        account = getIntent().getParcelableExtra(EXTRA_ACCOUNT);        setTitle(getString(R.string.settings_title, account.name));        getSupportActionBar().setDisplayHomeAsUpEnabled(true);        if (savedInstanceState == null)            getSupportFragmentManager().beginTransaction()                    .replace(android.R.id.content, AccountSettingsFragment.instantiate(this, AccountSettingsFragment.class.getName(), getIntent().getExtras()))                    .commit();    }    @Override    public boolean onOptionsItemSelected(MenuItem item) {        if (item.getItemId() == android.R.id.home) {            Intent intent = new Intent(this, AccountActivity.class);            intent.putExtra(AccountActivity.EXTRA_ACCOUNT, account);            NavUtils.navigateUpTo(this, intent);            return true;        } else            return false;    }    public static class AccountSettingsFragment extends PreferenceFragmentCompat {        Account account;        @Override        public void onCreate(Bundle savedInstanceState) {            super.onCreate(savedInstanceState);            account = getArguments().getParcelable(EXTRA_ACCOUNT);            refresh();        }        @Override        public void onCreatePreferences(Bundle bundle, String s) {            addPreferencesFromResource(R.xml.settings_account);        }        public void refresh() {            final AccountSettings settings;            try {                settings = new AccountSettings(getActivity(), account);            } catch(InvalidAccountException e) {                App.log.log(Level.INFO, "Account is invalid or doesn't exist (anymore)", e);                getActivity().finish();                return;            }            // category: authentication            final EditTextPreference prefUserName = (EditTextPreference)findPreference("username");            prefUserName.setSummary(settings.username());            prefUserName.setText(settings.username());            prefUserName.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {                @Override                public boolean onPreferenceChange(Preference preference, Object newValue) {                    settings.username((String)newValue);                    refresh();                    return false;                }            });            final EditTextPreference prefPassword = (EditTextPreference)findPreference("password");            prefPassword.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {                @Override                public boolean onPreferenceChange(Preference preference, Object newValue) {                    settings.password((String)newValue);                    refresh();                    return false;                }            });            // category: synchronization            final ListPreference prefSyncContacts = (ListPreference)findPreference("sync_interval_contacts");            final Long syncIntervalContacts = settings.getSyncInterval(ContactsContract.AUTHORITY);            if (syncIntervalContacts != null) {                prefSyncContacts.setValue(syncIntervalContacts.toString());                if (syncIntervalContacts == AccountSettings.SYNC_INTERVAL_MANUALLY)                    prefSyncContacts.setSummary(R.string.settings_sync_summary_manually);                else                    prefSyncContacts.setSummary(getString(R.string.settings_sync_summary_periodically, syncIntervalContacts / 60));                prefSyncContacts.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {                    @Override                    public boolean onPreferenceChange(Preference preference, Object newValue) {                        settings.setSyncInterval(ContactsContract.AUTHORITY, Long.parseLong((String)newValue));                        refresh();                        return false;                    }                });            } else {                prefSyncContacts.setEnabled(false);                prefSyncContacts.setSummary(R.string.settings_sync_summary_not_available);            }            final ListPreference prefSyncCalendars = (ListPreference)findPreference("sync_interval_calendars");            final Long syncIntervalCalendars = settings.getSyncInterval(CalendarContract.AUTHORITY);            if (syncIntervalCalendars != null) {                prefSyncCalendars.setValue(syncIntervalCalendars.toString());                if (syncIntervalCalendars == AccountSettings.SYNC_INTERVAL_MANUALLY)                    prefSyncCalendars.setSummary(R.string.settings_sync_summary_manually);                else                    prefSyncCalendars.setSummary(getString(R.string.settings_sync_summary_periodically, syncIntervalCalendars / 60));                prefSyncCalendars.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {                    @Override                    public boolean onPreferenceChange(Preference preference, Object newValue) {                        settings.setSyncInterval(CalendarContract.AUTHORITY, Long.parseLong((String)newValue));                        refresh();                        return false;                    }                });            } else {                prefSyncCalendars.setEnabled(false);                prefSyncCalendars.setSummary(R.string.settings_sync_summary_not_available);            }            final ListPreference prefSyncTasks = (ListPreference)findPreference("sync_interval_tasks");            final Long syncIntervalTasks = settings.getSyncInterval(TaskProvider.ProviderName.OpenTasks.authority);            if (syncIntervalTasks != null) {                prefSyncTasks.setValue(syncIntervalTasks.toString());                if (syncIntervalTasks == AccountSettings.SYNC_INTERVAL_MANUALLY)                    prefSyncTasks.setSummary(R.string.settings_sync_summary_manually);                else                    prefSyncTasks.setSummary(getString(R.string.settings_sync_summary_periodically, syncIntervalTasks / 60));                prefSyncTasks.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {                    @Override                    public boolean onPreferenceChange(Preference preference, Object newValue) {                        settings.setSyncInterval(TaskProvider.ProviderName.OpenTasks.authority, Long.parseLong((String)newValue));                        refresh();                        return false;                    }                });            } else {                prefSyncTasks.setEnabled(false);                prefSyncTasks.setSummary(R.string.settings_sync_summary_not_available);            }            final SwitchPreferenceCompat prefWifiOnly = (SwitchPreferenceCompat)findPreference("sync_wifi_only");            prefWifiOnly.setChecked(settings.getSyncWifiOnly());            prefWifiOnly.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {                @Override                public boolean onPreferenceChange(Preference preference, Object wifiOnly) {                    settings.setSyncWiFiOnly((Boolean)wifiOnly);                    refresh();                    return false;                }            });            final EditTextPreference prefWifiOnlySSID = (EditTextPreference)findPreference("sync_wifi_only_ssid");            final String onlySSID = settings.getSyncWifiOnlySSID();            prefWifiOnlySSID.setText(onlySSID);            if (onlySSID != null)                prefWifiOnlySSID.setSummary(getString(R.string.settings_sync_wifi_only_ssid_on, onlySSID));            else                prefWifiOnlySSID.setSummary(R.string.settings_sync_wifi_only_ssid_off);            prefWifiOnlySSID.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {                @Override                public boolean onPreferenceChange(Preference preference, Object newValue) {                    String ssid = (String)newValue;                    settings.setSyncWifiOnlySSID(!TextUtils.isEmpty(ssid) ? ssid : null);                    refresh();                    return false;                }            });            // category: CardDAV            final SwitchPreferenceCompat prefRFC6868 = (SwitchPreferenceCompat)findPreference("vcard_rfc6868");            if (syncIntervalContacts != null) {                prefRFC6868.setChecked(settings.getVCardRFC6868());                prefRFC6868.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {                    @Override                    public boolean onPreferenceChange(Preference preference, Object o) {                        settings.setVCardRFC6868((Boolean)o);                        refresh();                        return false;                    }                });            } else                prefRFC6868.setEnabled(false);            final ListPreference prefGroupMethod = (ListPreference)findPreference("contact_group_method");            if (syncIntervalContacts != null) {                prefGroupMethod.setValue(settings.getGroupMethod().name());                prefGroupMethod.setSummary(prefGroupMethod.getEntry());                prefGroupMethod.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {                    @Override                    public boolean onPreferenceChange(Preference preference, Object o) {                        String name = (String)o;                        settings.setGroupMethod(GroupMethod.valueOf(name));                        refresh();                        return false;                    }                });            } else                prefGroupMethod.setEnabled(false);            // category: CalDAV            final EditTextPreference prefTimeRangePastDays = (EditTextPreference)findPreference("time_range_past_days");            if (syncIntervalCalendars != null) {                Integer pastDays = settings.getTimeRangePastDays();                if (pastDays != null) {                    prefTimeRangePastDays.setText(pastDays.toString());                    prefTimeRangePastDays.setSummary(getResources().getQuantityString(R.plurals.settings_sync_time_range_past_days, pastDays, pastDays));                } else {                    prefTimeRangePastDays.setText(null);                    prefTimeRangePastDays.setSummary(R.string.settings_sync_time_range_past_none);                }                prefTimeRangePastDays.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {                    @Override                    public boolean onPreferenceChange(Preference preference, Object newValue) {                        int days;                        try {                            days = Integer.parseInt((String)newValue);                        } catch(NumberFormatException ignored) {                            days = -1;                        }                        settings.setTimeRangePastDays(days < 0 ? null : days);                        refresh();                        return false;                    }                });            } else                prefTimeRangePastDays.setEnabled(false);            final SwitchPreferenceCompat prefManageColors = (SwitchPreferenceCompat)findPreference("manage_calendar_colors");            if (syncIntervalCalendars != null || syncIntervalTasks != null) {                prefManageColors.setChecked(settings.getManageCalendarColors());                prefManageColors.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {                    @Override                    public boolean onPreferenceChange(Preference preference, Object newValue) {                        settings.setManageCalendarColors((Boolean)newValue);                        refresh();                        return false;                    }                });            } else                prefManageColors.setEnabled(false);        }    }}

2.DilogFragment

public class StartupDialogFragment extends DialogFragment {    public static final String            HINT_BATTERY_OPTIMIZATIONS = "hint_BatteryOptimizations",            HINT_GOOGLE_PLAY_ACCOUNTS_REMOVED = "hint_GooglePlayAccountsRemoved",            HINT_OPENTASKS_NOT_INSTALLED = "hint_OpenTasksNotInstalled";    private static final String ARGS_MODE = "mode";    enum Mode {        BATTERY_OPTIMIZATIONS,        DEVELOPMENT_VERSION,        FDROID_DONATE,        GOOGLE_PLAY_ACCOUNTS_REMOVED,        OPENTASKS_NOT_INSTALLED    }    public static StartupDialogFragment[] getStartupDialogs(Context context) {        List<StartupDialogFragment> dialogs = new LinkedList<>();        @Cleanup ServiceDB.OpenHelper dbHelper = new ServiceDB.OpenHelper(context);        Settings settings  = new Settings(dbHelper.getReadableDatabase());        if (BuildConfig.VERSION_NAME.contains("-alpha") || BuildConfig.VERSION_NAME.contains("-beta") || BuildConfig.VERSION_NAME.contains("-rc"))            dialogs.add(StartupDialogFragment.instantiate(Mode.DEVELOPMENT_VERSION));        else            dialogs.add(StartupDialogFragment.instantiate(Mode.FDROID_DONATE));        // battery optimization whitelisting        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && settings.getBoolean(HINT_BATTERY_OPTIMIZATIONS, true)) {            PowerManager powerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);            if (!powerManager.isIgnoringBatteryOptimizations(BuildConfig.APPLICATION_ID))                dialogs.add(StartupDialogFragment.instantiate(Mode.BATTERY_OPTIMIZATIONS));        }        // OpenTasks information        if (!LocalTaskList.tasksProviderAvailable(context) && settings.getBoolean(HINT_OPENTASKS_NOT_INSTALLED, true))            dialogs.add(StartupDialogFragment.instantiate(Mode.OPENTASKS_NOT_INSTALLED));        Collections.reverse(dialogs);        return dialogs.toArray(new StartupDialogFragment[dialogs.size()]);    }    public static StartupDialogFragment instantiate(Mode mode) {        StartupDialogFragment frag = new StartupDialogFragment();        Bundle args = new Bundle(1);        args.putString(ARGS_MODE, mode.name());        frag.setArguments(args);        return frag;    }    @NonNull    @Override    @TargetApi(Build.VERSION_CODES.M)    @SuppressLint("BatteryLife")    public Dialog onCreateDialog(Bundle savedInstanceState) {        setCancelable(false);        final ServiceDB.OpenHelper dbHelper = new ServiceDB.OpenHelper(getContext());        Mode mode = Mode.valueOf(getArguments().getString(ARGS_MODE));        switch (mode) {            case BATTERY_OPTIMIZATIONS:                return new AlertDialog.Builder(getActivity())                        .setTitle(R.string.startup_battery_optimization)                        .setMessage(R.string.startup_battery_optimization_message)                        .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {                            @Override                            public void onClick(DialogInterface dialog, int which) {                            }                        })                        .setNeutralButton(R.string.startup_battery_optimization_disable, new DialogInterface.OnClickListener() {                            @Override                            public void onClick(DialogInterface dialog, int which) {                                Intent intent = new Intent(android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,                                        Uri.parse("package:" + BuildConfig.APPLICATION_ID));                                getContext().startActivity(intent);                            }                        })                        .setNegativeButton(R.string.startup_dont_show_again, new DialogInterface.OnClickListener() {                            @Override                            public void onClick(DialogInterface dialog, int which) {                                Settings settings = new Settings(dbHelper.getWritableDatabase());                                settings.putBoolean(HINT_BATTERY_OPTIMIZATIONS, false);                            }                        })                        .create();            case DEVELOPMENT_VERSION:                return new AlertDialog.Builder(getActivity())                        .setIcon(R.mipmap.ic_launcher)                        .setTitle(R.string.startup_development_version)                        .setMessage(R.string.startup_development_version_message)                        .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {                            @Override                            public void onClick(DialogInterface dialog, int which) {                            }                        })                        .setNeutralButton(R.string.startup_development_version_give_feedback, new DialogInterface.OnClickListener() {                            @Override                            public void onClick(DialogInterface dialog, int which) {                                startActivity(new Intent(Intent.ACTION_VIEW, Constants.webUri.buildUpon().appendEncodedPath("forums/").build()));                            }                        })                        .create();            case FDROID_DONATE:                return new AlertDialog.Builder(getActivity())                        .setIcon(R.mipmap.ic_launcher)                        .setTitle(R.string.startup_donate)                        .setMessage(R.string.startup_donate_message)                        .setPositiveButton(R.string.startup_donate_now, new DialogInterface.OnClickListener() {                            @Override                            public void onClick(DialogInterface dialog, int which) {                                startActivity(new Intent(Intent.ACTION_VIEW, Constants.webUri.buildUpon().appendEncodedPath("donate/").build()));                            }                        })                        .setNegativeButton(R.string.startup_donate_later, new DialogInterface.OnClickListener() {                            @Override                            public void onClick(DialogInterface dialog, int which) {                            }                        })                        .create();            case OPENTASKS_NOT_INSTALLED:                StringBuilder builder = new StringBuilder(getString(R.string.startup_opentasks_not_installed_message));                if (Build.VERSION.SDK_INT < 23)                    builder.append("\n\n").append(getString(R.string.startup_opentasks_reinstall_davdroid));                return new AlertDialog.Builder(getActivity())                        .setIcon(R.drawable.ic_alarm_on_dark)                        .setTitle(R.string.startup_opentasks_not_installed)                        .setMessage(builder.toString())                        .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {                            @Override                            public void onClick(DialogInterface dialog, int which) {                            }                        })                        .setNeutralButton(R.string.startup_opentasks_not_installed_install, new DialogInterface.OnClickListener() {                            @Override                            public void onClick(DialogInterface dialog, int which) {                                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=org.dmfs.tasks"));                                if (intent.resolveActivity(getContext().getPackageManager()) != null)                                    getContext().startActivity(intent);                                else                                    App.log.warning("No market app available, can't install OpenTasks");                            }                        })                        .setNegativeButton(R.string.startup_dont_show_again, new DialogInterface.OnClickListener() {                            @Override                            public void onClick(DialogInterface dialog, int which) {                                Settings settings = new Settings(dbHelper.getWritableDatabase());                                settings.putBoolean(HINT_OPENTASKS_NOT_INSTALLED, false);                            }                        })                        .create();        }        throw new IllegalArgumentException(/* illegal mode argument */);    }    private static String installedFrom(Context context) {        try {            return context.getPackageManager().getInstallerPackageName(context.getPackageName());        } catch(IllegalArgumentException e) {            return null;        }    }}

 

4.静态ListFragment

/* * Copyright © 2013 – 2016 Ricki Hirner (bitfire web engineering). * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html */package at.bitfire.davdroid.ui;import android.accounts.Account;import android.accounts.AccountManager;import android.accounts.OnAccountsUpdateListener;import android.annotation.SuppressLint;import android.content.Context;import android.content.Intent;import android.os.Bundle;import android.support.v4.app.ListFragment;import android.support.v4.app.LoaderManager;import android.support.v4.content.AsyncTaskLoader;import android.support.v4.content.Loader;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.AbsListView;import android.widget.AdapterView;import android.widget.ArrayAdapter;import android.widget.ListView;import android.widget.TextView;import at.bitfire.davdroid.AccountsChangedReceiver;import at.bitfire.davdroid.Constants;import at.bitfire.davdroid.R;public class AccountListFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Account[]>, AdapterView.OnItemClickListener {    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        setListAdapter(new AccountListAdapter(getContext()));        return inflater.inflate(R.layout.account_list, container, false);    }    @Override    public void onViewCreated(View view, Bundle savedInstanceState) {        super.onViewCreated(view, savedInstanceState);        getLoaderManager().initLoader(0, getArguments(), this);        ListView list = getListView();        list.setOnItemClickListener(this);        list.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);    }    @Override    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {        Account account = (Account)getListAdapter().getItem(position);        Intent intent = new Intent(getContext(), AccountActivity.class);        intent.putExtra(AccountActivity.EXTRA_ACCOUNT, account);        startActivity(intent);    }    // loader    @Override    public Loader<Account[]> onCreateLoader(int id, Bundle args) {        return new AccountLoader(getContext());    }    @Override    public void onLoadFinished(Loader<Account[]> loader, Account[] accounts) {        AccountListAdapter adapter = (AccountListAdapter)getListAdapter();        adapter.clear();        adapter.addAll(accounts);    }    @Override    public void onLoaderReset(Loader<Account[]> loader) {        ((AccountListAdapter)getListAdapter()).clear();    }    private static class AccountLoader extends AsyncTaskLoader<Account[]> implements OnAccountsUpdateListener {        private final AccountManager accountManager;        public AccountLoader(Context context) {            super(context);            accountManager = AccountManager.get(context);        }        @Override        protected void onStartLoading() {            AccountsChangedReceiver.registerListener(this, true);        }        @Override        protected void onStopLoading() {            AccountsChangedReceiver.unregisterListener(this);        }        @Override        public void onAccountsUpdated(Account[] accounts) {            forceLoad();        }        @Override        @SuppressLint("MissingPermission")        public Account[] loadInBackground() {            return accountManager.getAccountsByType(Constants.ACCOUNT_TYPE);        }    }    // list adapter    static class AccountListAdapter extends ArrayAdapter<Account> {        public AccountListAdapter(Context context) {            super(context, R.layout.account_list_item);        }        @Override        public View getView(int position, View v, ViewGroup parent) {            if (v == null)                v = LayoutInflater.from(getContext()).inflate(R.layout.account_list_item, parent, false);            Account account = getItem(position);            TextView tv = (TextView)v.findViewById(R.id.account_name);            tv.setText(account.name);            return v;        }    }}
<android.support.design.widget.CoordinatorLayout    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"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="at.bitfire.davdroid.ui.AccountsActivity">    <android.support.design.widget.AppBarLayout        android:layout_width="match_parent"        android:layout_height="wrap_content">        <android.support.v7.widget.Toolbar            app:theme="@style/ThemeOverlay.AppCompat.ActionBar"            android:id="@+id/toolbar"            android:layout_width="match_parent"            android:layout_height="?attr/actionBarSize"            android:background="?attr/colorPrimary"/>    </android.support.design.widget.AppBarLayout>    <fragment        class="at.bitfire.davdroid.ui.AccountListFragment"        android:id="@+id/account_list"        android:layout_width="match_parent"        android:layout_height="match_parent"        tools:layout="@layout/account_list"        app:layout_scrollFlags="scroll"        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>    <android.support.design.widget.FloatingActionButton        android:id="@+id/fab"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_gravity="bottom|end"        android:layout_margin="@dimen/fab_margin"        android:src="@drawable/ic_add_light"/></android.support.design.widget.CoordinatorLayout>

5 android:empty android:list

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <ListView        android:id="@id/android:list"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:padding="8dp"        android:divider="@android:color/transparent"        android:background="@android:color/transparent"        android:cacheColorHint="@android:color/transparent"/>    <TextView        android:id="@id/android:empty"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_margin="16dp"        android:gravity="center"        android:textAppearance="@style/TextAppearance.AppCompat.Large"        android:text="@string/account_list_empty" /></LinearLayout>

6.Scrollview切换

/*
 * Copyright © 2013 – 2016 Ricki Hirner (bitfire web engineering).
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 */

package at.bitfire.davdroid.ui.setup;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RadioButton;

import org.apache.commons.lang3.StringUtils;

import java.net.IDN;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.logging.Level;

import at.bitfire.dav4android.Constants;
import at.bitfire.davdroid.R;
import at.bitfire.davdroid.ui.widget.EditPassword;

public class LoginCredentialsFragment extends Fragment implements CompoundButton.OnCheckedChangeListener {

    RadioButton radioUseEmail;
    LinearLayout emailDetails;
    EditText editEmailAddress;
    EditPassword editEmailPassword;

    RadioButton radioUseURL;
    LinearLayout urlDetails;
    EditText editBaseURL, editUserName;
    EditPassword editUrlPassword;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.login_credentials_fragment, container, false);

        radioUseEmail = (RadioButton)v.findViewById(R.id.login_type_email);
        emailDetails = (LinearLayout)v.findViewById(R.id.login_type_email_details);
        editEmailAddress = (EditText)v.findViewById(R.id.email_address);
        editEmailPassword = (EditPassword)v.findViewById(R.id.email_password);

        radioUseURL = (RadioButton)v.findViewById(R.id.login_type_url);
        urlDetails = (LinearLayout)v.findViewById(R.id.login_type_url_details);
        editBaseURL = (EditText)v.findViewById(R.id.base_url);
        editUserName = (EditText)v.findViewById(R.id.user_name);
        editUrlPassword = (EditPassword)v.findViewById(R.id.url_password);

        radioUseEmail.setOnCheckedChangeListener(this);
        radioUseURL.setOnCheckedChangeListener(this);

        if (savedInstanceState == null) {
            // first call

            Activity activity = getActivity();
            Intent intent = (activity != null) ? activity.getIntent() : null;
            if (intent != null) {
                // we've got initial login data
                String  url = intent.getStringExtra(LoginActivity.EXTRA_URL),
                        username = intent.getStringExtra(LoginActivity.EXTRA_USERNAME),
                        password = intent.getStringExtra(LoginActivity.EXTRA_PASSWORD);

                if (url != null) {
                    radioUseURL.setChecked(true);
                    editBaseURL.setText(url);
                    editUserName.setText(username);
                    editUrlPassword.setText(password);
                } else {
                    radioUseEmail.setChecked(true);
                    editEmailAddress.setText(username);
                    editEmailPassword.setText(password);
                }

            } else
                radioUseEmail.setChecked(true);
        }

        final Button login = (Button)v.findViewById(R.id.login);
        login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                LoginCredentials credentials = validateLoginData();
                if (credentials != null)
                    DetectConfigurationFragment.newInstance(credentials).show(getFragmentManager(), null);
            }
        });

        return v;
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (isChecked) {
            boolean loginByEmail = buttonView == radioUseEmail;
            emailDetails.setVisibility(loginByEmail ? View.VISIBLE : View.GONE);
            urlDetails.setVisibility(loginByEmail ? View.GONE : View.VISIBLE);
            (loginByEmail ? editEmailAddress : editBaseURL).requestFocus();
        }
    }

    protected LoginCredentials validateLoginData() {
        if (radioUseEmail.isChecked()) {
            URI uri = null;
            boolean valid = true;

            String email = editEmailAddress.getText().toString();
            if (!email.matches(".+@.+")) {
                editEmailAddress.setError(getString(R.string.login_email_address_error));
                valid = false;
            } else
                try {
                    uri = new URI("mailto", email, null);
                } catch (URISyntaxException e) {
                    editEmailAddress.setError(e.getLocalizedMessage());
                    valid = false;
                }

            String password = editEmailPassword.getText().toString();
            if (password.isEmpty()) {
                editEmailPassword.setError(getString(R.string.login_password_required));
                valid = false;
            }

            return valid ? new LoginCredentials(uri, email, password) : null;

        } else if (radioUseURL.isChecked()) {
            URI uri = null;
            boolean valid = true;

            Uri baseUrl = Uri.parse(editBaseURL.getText().toString());
            String scheme = baseUrl.getScheme();
            if ("https".equalsIgnoreCase(scheme) || "http".equalsIgnoreCase(scheme)) {
                String host = baseUrl.getHost();
                if (StringUtils.isEmpty(host)) {
                    editBaseURL.setError(getString(R.string.login_url_host_name_required));
                    valid = false;
                } else
                    try {
                        host = IDN.toASCII(host);
                    } catch(IllegalArgumentException e) {
                        Constants.log.log(Level.WARNING, "Host name not conforming to RFC 3490", e);
                    }

                String path = baseUrl.getEncodedPath();
                int port = baseUrl.getPort();
                try {
                    uri = new URI(baseUrl.getScheme(), null, host, port, path, null, null);
                } catch (URISyntaxException e) {
                    editBaseURL.setError(e.getLocalizedMessage());
                    valid = false;
                }
            } else {
                editBaseURL.setError(getString(R.string.login_url_must_be_http_or_https));
                valid = false;
            }

            String userName = editUserName.getText().toString();
            if (userName.isEmpty()) {
                editUserName.setError(getString(R.string.login_user_name_required));
                valid = false;
            }

            String password = editUrlPassword.getText().toString();
            if (password.isEmpty()) {
                editUrlPassword.setError(getString(R.string.login_password_required));
                valid = false;
            }

            return valid ? new LoginCredentials(uri, userName, password) : null;
        }

        return null;
    }

}

<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright © 2013 – 2016 Ricki Hirner (bitfire web engineering).
  ~ All rights reserved. This program and the accompanying materials
  ~ are made available under the terms of the GNU Public License v3.0
  ~ which accompanies this distribution, and is available at
  ~ http://www.gnu.org/licenses/gpl.html
  -->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <!-- We don't want the keyboard up when the user arrives in this initial screen -->
    <View android:layout_height="0dp"
          android:layout_width="0dp"
          android:focusable="true"
          android:focusableInTouchMode="true"
          android:contentDescription="@null"
          android:importantForAccessibility="no" tools:ignore="UnusedAttribute">
        <requestFocus/>
    </View>

    <ScrollView android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:layout_margin="@dimen/activity_margin">

        <RadioGroup
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:animateLayoutChanges="true">

            <RadioButton
                android:id="@+id/login_type_email"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/login_type_email"
                android:paddingLeft="14dp" tools:ignore="RtlSymmetry"
                style="@style/login_type_headline"/>

            <LinearLayout
                android:id="@+id/login_type_email_details"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <EditText
                    android:id="@+id/email_address"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="@string/login_email_address"
                    android:inputType="textEmailAddress"/>
                <at.bitfire.davdroid.ui.widget.EditPassword
                    android:id="@+id/email_password"
                    android:hint="@string/login_password"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"/>
            </LinearLayout>

            <RadioButton
                android:id="@+id/login_type_url"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/login_type_url"
                android:layout_marginTop="16dp"
                android:paddingLeft="14dp" tools:ignore="RtlSymmetry"
                style="@style/login_type_headline"/>

            <LinearLayout
                android:id="@+id/login_type_url_details"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <EditText
                    android:id="@+id/base_url"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="@string/login_base_url"
                    android:inputType="textUri"/>
                <EditText
                    android:id="@+id/user_name"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="@string/login_user_name"
                    android:inputType="textEmailAddress"/>
                <at.bitfire.davdroid.ui.widget.EditPassword
                    android:id="@+id/url_password"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="@string/login_password"/>

            </LinearLayout>

        </RadioGroup>
    </ScrollView>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="@style/stepper_nav_bar">

        <Space
            android:layout_width="0dp"
            android:layout_weight="1"
            style="@style/stepper_nav_button"/>

        <Button
            android:id="@+id/login"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:text="@string/login_login"
            style="@style/stepper_nav_button"/>

    </LinearLayout>
</LinearLayout>

5 ListView

public class MaximizedListView extends ListView {    public MaximizedListView(Context context, AttributeSet attrs) {        super(context, attrs);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int widthMode = MeasureSpec.getMode(widthMeasureSpec),            widthSize = MeasureSpec.getSize(widthMeasureSpec),            heightMode = MeasureSpec.getMode(heightMeasureSpec),            heightSize = MeasureSpec.getSize(heightMeasureSpec);        int width = 0, height = 0;        if (widthMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.AT_MOST)            width = widthSize;        if (heightMode == MeasureSpec.EXACTLY)            height = heightSize;        else {            ListAdapter listAdapter = getAdapter();            if (listAdapter != null) {                int widthSpec = View.MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);                for (int i = 0; i < listAdapter.getCount(); i++) {                    View listItem = listAdapter.getView(i, null, this);                    listItem.measure(widthSpec, View.MeasureSpec.UNSPECIFIED);                    height += listItem.getMeasuredHeight();                }                height += getDividerHeight() * (listAdapter.getCount() - 1);            }        }        setMeasuredDimension(width, height);    }}
上一篇下一篇

猜你喜欢

热点阅读