davdroid

作者: 81bad73e9053 | 来源:发表于2016-09-22 10:37 被阅读276次

    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);    }}
    

    相关文章

      网友评论

          本文标题:davdroid

          本文链接:https://www.haomeiwen.com/subject/nyerkttx.html