Commit f055d88e authored by DESKTOP-NFGF3PG\zxa01's avatar DESKTOP-NFGF3PG\zxa01

commit mvvm

parent 769cc094
......@@ -3,11 +3,6 @@
<component name="WizardSettings">
<option name="children">
<map>
<entry key="imageWizard">
<value>
<PersistentState />
</value>
</entry>
<entry key="vectorWizard">
<value>
<PersistentState>
......@@ -23,7 +18,7 @@
<PersistentState>
<option name="values">
<map>
<entry key="url" value="jar:file:/C:/Program%20Files/Android/Android%20Studio/plugins/android/lib/android.jar!/images/material_design_icons/action/ic_settings_black_24dp.xml" />
<entry key="url" value="jar:file:/C:/Program%20Files/Android/Android%20Studio/plugins/android/lib/android.jar!/images/material_design_icons/content/ic_add_black_24dp.xml" />
</map>
</option>
</PersistentState>
......@@ -33,7 +28,8 @@
</option>
<option name="values">
<map>
<entry key="outputName" value="ic_settings_black_24dp" />
<entry key="color" value="ffffff" />
<entry key="outputName" value="ic_add_black_24dp" />
<entry key="sourceFile" value="C:\Users\zxa01" />
</map>
</option>
......
......@@ -3,6 +3,9 @@
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<compositeConfiguration>
<compositeBuild compositeDefinitionSource="SCRIPT" />
</compositeConfiguration>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
......
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Kotlin2JsCompilerArguments">
<option name="sourceMapEmbedSources" />
</component>
</project>
\ No newline at end of file
......@@ -5,7 +5,7 @@
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="7">
<list size="10">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
......@@ -13,23 +13,29 @@
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
<item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
<item index="7" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.Nullable" />
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableDecl" />
<item index="9" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableType" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="6">
<list size="9">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
<item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
<item index="6" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.NonNull" />
<item index="7" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullDecl" />
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullType" />
</list>
</value>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
......
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="" vcs="Git" />
</component>
</project>
\ No newline at end of file
......@@ -12,10 +12,17 @@ android {
}
buildTypes {
release {
minifyEnabled false
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
dataBinding {
enabled = true
}
compileOptions {
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
}
}
dependencies {
......@@ -28,6 +35,8 @@ dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
// 可移除
implementation 'com.jakewharton:butterknife:9.0.0-rc2'
annotationProcessor 'com.jakewharton:butterknife-compiler:9.0.0-rc2'
}
......@@ -2,6 +2,11 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.zxa01.iotclient">
<!-- To auto-complete the email text field in the login form with the user's emails -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
......@@ -9,15 +14,26 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".home.HomeActivity"
android:label="@string/app_name">
android:name=".login.LoginActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".home.HomeActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan"
></activity>
</application>
</manifest>
\ No newline at end of file
package com.example.zxa01.iotclient.base;
public interface BasePresenter<T> {
/**
* Binds presenter with a view when resumed. The Presenter will perform initialization here.
*
* @param view the view associated with this presenter
*/
void takeView(T view);
/**
* Drops the reference to the view when destroyed
*/
void dropView();
}
package com.example.zxa01.iotclient.base;
public interface BaseView<T> {
}
package com.example.zxa01.iotclient.home;
import android.content.Intent;
import android.databinding.DataBindingUtil;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;
import com.example.zxa01.iotclient.R;
import com.example.zxa01.iotclient.device.DeviceFragment;
import com.example.zxa01.iotclient.privacy.PrivacyFragment;
import com.example.zxa01.iotclient.setting.SettingFragment;
import com.example.zxa01.iotclient.databinding.ActivityHomeBinding;
import com.example.zxa01.iotclient.home.device.DeviceFragment;
import com.example.zxa01.iotclient.home.device.DeviceViewModel;
import com.example.zxa01.iotclient.home.privacy.PrivacyFragment;
import com.example.zxa01.iotclient.home.setting.SettingFragment;
import butterknife.BindView;
import butterknife.ButterKnife;
public class HomeActivity extends AppCompatActivity implements
DeviceFragment.OnFragmentInteractionListener,
PrivacyFragment.OnFragmentInteractionListener,
SettingFragment.OnFragmentInteractionListener {
public class HomeActivity extends AppCompatActivity
implements DeviceFragment.OnFragmentInteractionListener
, PrivacyFragment.OnFragmentInteractionListener, SettingFragment.OnFragmentInteractionListener {
/* data binding */
private ActivityHomeBinding binding;
DeviceFragment mDeviceFragment = new DeviceFragment();
PrivacyFragment mPrivacyFragment = new PrivacyFragment();
SettingFragment mSettingFragment = new SettingFragment();
@BindView(R.id.navigation)
BottomNavigationView navigation;
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_home:
showFragment(mDeviceFragment);
return true;
case R.id.navigation_privacy:
showFragment(mPrivacyFragment);
return true;
case R.id.navigation_setting:
showFragment(mSettingFragment);
return true;
}
return false;
}
};
/* fragments of HomeActivity */
private DeviceFragment mDeviceFragment = new DeviceFragment();
private PrivacyFragment mPrivacyFragment = new PrivacyFragment();
private SettingFragment mSettingFragment = new SettingFragment();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
ButterKnife.bind(this);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
binding = DataBindingUtil.setContentView(this,R.layout.activity_home);
/* init */
setupFragment(binding.navigation);
showFragment(mDeviceFragment);
}
@Override
public void onDeviceFragment(Uri uri) {
// do nothing
}
@Override
public void onPrivacyFragment(Uri uri) {
// do nothing
}
@Override
public void onSettingFragment(Uri uri) {
// do nothing
}
/* onItemSelected of fragment */
private void setupFragment(BottomNavigationView view){
view.setOnNavigationItemSelectedListener(
menuItem -> {
switch (menuItem.getItemId()) {
case R.id.navigation_home:
showFragment(mDeviceFragment);
return true;
case R.id.navigation_privacy:
showFragment(mPrivacyFragment);
return true;
case R.id.navigation_setting:
showFragment(mSettingFragment);
return true;
}
return false;
}
);
}
/* show of fragment */
private void showFragment(Fragment fragment) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.home_fragment_layout, fragment)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.commit();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == 0) {
if (resultCode == RESULT_OK) {
new DeviceViewModel().createDevice(intent.getStringExtra("SCAN_RESULT"));
}
}
}
}
package com.example.zxa01.iotclient.device;
package com.example.zxa01.iotclient.home.device;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
......@@ -7,6 +7,7 @@ import android.view.ViewGroup;
import android.widget.TextView;
import com.example.zxa01.iotclient.R;
import com.example.zxa01.iotclient.pojo.Device;
import java.util.LinkedList;
......@@ -51,7 +52,6 @@ public class DeviceAdapter extends RecyclerView.Adapter<DeviceAdapter.MyViewHold
this.textDeviceName = view.findViewById(R.id.text_device_name);
this.textDeviceSubtitle = view.findViewById(R.id.text_device_subtitle);
this.textDeviceStatus = view.findViewById(R.id.text_device_status);
}
@Override
......
package com.example.zxa01.iotclient.home.device;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Intent;
import android.databinding.DataBindingUtil;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.zxa01.iotclient.R;
import com.example.zxa01.iotclient.databinding.FragmentDeviceCreateBinding;
public class DeviceCreateFragment extends DialogFragment {
private static final String QRCODE_MARKET = "market://details?id=com.google.zxing.client.android";
private static final String QRCODE_INTENT = "com.google.zxing.client.android.SCAN";
private static final String QRCODE_MODE = "SCAN_MODE";
private static final String QRCODE_CODE_MODE = "QR_CODE_MODE";
private static final int QRCODE_REQUEST_CODE = 0;
private FragmentDeviceCreateBinding binding;
public DeviceCreateFragment() {
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setView(R.layout.fragment_device_create)
.setNeutralButton(R.string.button_qrcode,
(dialog, whichButton) -> {
qrcodeIntent();
}
)
.setPositiveButton(R.string.button_correct,
(dialog, whichButton) -> {
new DeviceViewModel().createDevice("address");
}
)
.setNegativeButton(R.string.button_cancel, (dialog, whichButton) -> {
})
.create();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_device_create, container, false);
return binding.getRoot();
}
private void qrcodeIntent() {
try {
startActivityForResult(
new Intent(QRCODE_INTENT)
.putExtra(QRCODE_MODE, QRCODE_CODE_MODE)
, QRCODE_REQUEST_CODE);
} catch (Exception e) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(QRCODE_MARKET)));
}
}
}
package com.example.zxa01.iotclient.home.device;
import android.content.Context;
import android.databinding.DataBindingUtil;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.zxa01.iotclient.R;
import com.example.zxa01.iotclient.databinding.FragmentDeviceBinding;
public class DeviceFragment extends Fragment {
private FragmentDeviceBinding binding;
private DeviceViewModel viewModel = new DeviceViewModel();
public DeviceFragment() {
}
public static DeviceFragment newInstance() {
return new DeviceFragment();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = DataBindingUtil.inflate(inflater,R.layout.fragment_device,container,false);
binding.setViewModel(viewModel);
refreshDevices(binding.deviceRecyclerView);
setupDialog(binding.fab);
return binding.getRoot();
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
}
@Override
public void onDetach() {
super.onDetach();
}
public interface OnFragmentInteractionListener {
void onDeviceFragment(Uri uri);
}
private void refreshDevices(RecyclerView view){
view.setLayoutManager(new LinearLayoutManager(getActivity()));
view.setAdapter(new DeviceAdapter(viewModel.getDevices()));
}
private void setupDialog(View view){
view.setOnClickListener(item -> drawDialog());
}
private void drawDialog(){
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
Fragment fragment = getFragmentManager().findFragmentByTag(String.valueOf(R.string.dialog));
if (fragment != null) {
fragmentTransaction.remove(fragment);
}
fragmentTransaction.addToBackStack(null);
new DeviceCreateFragment().show(fragmentTransaction, String.valueOf(R.string.dialog));
}
}
package com.example.zxa01.iotclient.home.device;
import android.arch.lifecycle.ViewModel;
import com.example.zxa01.iotclient.home.service.CommonService;
import com.example.zxa01.iotclient.pojo.Device;
import java.util.LinkedList;
public class DeviceViewModel extends ViewModel {
private LinkedList<Device> mList = new LinkedList<>();
private CommonService service;
public DeviceViewModel(){
updateDevices();
}
public void updateDevices(){
// TODO api service.queryDevices();
Device device1 = new Device(1, "test1", "test", "test", true);
Device device2 = new Device(1, "test2", "test", "test", true);
Device device3 = new Device(1, "test3", "test", "test", true);
mList.add(device1);
mList.add(device2);
mList.add(device3);
}
public LinkedList<Device> getDevices() {
return mList;
}
public void createDevice(String address){
// TODO query and update mList
// service.createDevice(address);
}
}
package com.example.zxa01.iotclient.privacy;
package com.example.zxa01.iotclient.home.privacy;
import android.content.Context;
import android.net.Uri;
......
package com.example.zxa01.iotclient.home.service;
public class CommonService {
public void createDevice(String address){
}
public void queryDevices(){
}
public void connectGateway(String address){
}
}
package com.example.zxa01.iotclient.home.setting;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.example.zxa01.iotclient.R;
import com.example.zxa01.iotclient.pojo.Setting;
import java.util.LinkedList;
public class SettingAdapter extends RecyclerView.Adapter<SettingAdapter.MyViewHolder> {
private final LinkedList<Setting> mList;
public SettingAdapter(LinkedList<Setting> mList) {
this.mList = mList;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View mItemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_setting, parent, false);
return new MyViewHolder(mItemView);
}
@Override
public void onBindViewHolder(MyViewHolder mholder, int position) {
Setting setting = mList.get(position);
mholder.position = position;
mholder.textSettingKey.setText(setting.getKey());
mholder.textSettingValue.setText(setting.getValue());
}
@Override
public int getItemCount() {
return mList.size();
}
class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public int position;
public TextView textSettingKey;
public TextView textSettingValue;
public MyViewHolder(View view) {
super(view);
this.textSettingKey = view.findViewById(R.id.text_setting_key);
this.textSettingValue = view.findViewById(R.id.text_setting_value);
}
@Override
public void onClick(View v) {
}
}
}
\ No newline at end of file
package com.example.zxa01.iotclient.device;
package com.example.zxa01.iotclient.home.setting;
import android.content.Context;
import android.net.Uri;
......@@ -11,57 +11,61 @@ import android.view.View;
import android.view.ViewGroup;
import com.example.zxa01.iotclient.R;
import com.example.zxa01.iotclient.pojo.Setting;
import java.util.LinkedList;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
public class DeviceFragment extends Fragment {
public class SettingFragment extends Fragment {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private LinkedList<Device> mList = new LinkedList<>();
private RecyclerView mRecyclerView;
@BindView(R.id.setting_recycler_view)
RecyclerView settingRecyclerView;
Unbinder unbinder;
private String mParam1;
private String mParam2;
private LinkedList<Setting> mList = new LinkedList<>();
private RecyclerView mRecyclerView;
private OnFragmentInteractionListener mListener;
public DeviceFragment() {
public SettingFragment() {
// fake data
mList.add(new Setting("Gateway address", "192.168.2.69"));
mList.add(new Setting("Account", "Test"));
mList.add(new Setting("HTTP port", "8080"));
mList.add(new Setting("WebSocket port", "8081"));
mList.add(new Setting("Log out", "exchange account"));
}
public static DeviceFragment newInstance(String param1, String param2) {
DeviceFragment fragment = new DeviceFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
public static SettingFragment newInstance(String param1, String param2) {
return new SettingFragment();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_device, container, false);
buildRecyclerView(rootView);
return rootView;
View view = inflater.inflate(R.layout.fragment_setting, container, false);
unbinder = ButterKnife.bind(this, view);
if(savedInstanceState == null){
buildRecyclerView(view);
}
return view;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onDeviceFragment(uri);
mListener.onSettingFragment(uri);
}
}
......@@ -82,24 +86,19 @@ public class DeviceFragment extends Fragment {
mListener = null;
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
public interface OnFragmentInteractionListener {
void onDeviceFragment(Uri uri);
void onSettingFragment(Uri uri);
}
public void buildRecyclerView(View view){
// fake data
Device device1 = new Device(1, "test1", "test", "test", true);
Device device2 = new Device(1, "test2", "test", "test", true);
Device device3 = new Device(1, "test3", "test", "test", true);
mList.add(device1);
mList.add(device2);
mList.add(device3);
// recyclerView
mRecyclerView = view.findViewById(R.id.device_recycler_view);
mRecyclerView = view.findViewById(R.id.setting_recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecyclerView.setAdapter(new DeviceAdapter(mList));
mRecyclerView.setAdapter(new SettingAdapter(mList));
}
}
package com.example.zxa01.iotclient.login;
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import com.example.zxa01.iotclient.R;
import com.example.zxa01.iotclient.home.HomeActivity;
import butterknife.BindView;
import butterknife.ButterKnife;
public class LoginActivity extends AppCompatActivity {
@BindView(R.id.gateway)
EditText mGatewayView;
@BindView(R.id.account)
EditText mAccountView;
@BindView(R.id.password)
EditText mPasswordView;
@BindView(R.id.sign_in_button)
Button mSignInButton;
@BindView(R.id.linear_login_form)
LinearLayout mLayoutLoginForm;
private Activity activity = this;
private UserLoginTask mAuthTask = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
ButterKnife.bind(this);
mSignInButton.setOnClickListener(view -> attemptLogin());
mLayoutLoginForm.setOnClickListener(view -> hideKeyboard(activity));
}
private void attemptLogin() {
if (mAuthTask != null) {
return;
}
mAccountView.setError(null);
mPasswordView.setError(null);
String gateway = mGatewayView.getText().toString();
String account = mAccountView.getText().toString();
String password = mPasswordView.getText().toString();
boolean cancel = false;
View focusView = null;
// check
// if (!TextUtils.isEmpty(gateway) && !isLengthValid(gateway)) {
// mGatewayView.setError(getString(R.string.error_invalid_gateway));
// focusView = mGatewayView;
// cancel = true;
// }
// if (!TextUtils.isEmpty(password) && !isLengthValid(password)) {
// mPasswordView.setError(getString(R.string.error_invalid_password));
// focusView = mPasswordView;
// cancel = true;
// }
// if (TextUtils.isEmpty(account)) {
// mAccountView.setError(getString(R.string.error_field_required));
// focusView = mAccountView;
// cancel = true;
// } else if (!isLengthValid(account)) {
// mAccountView.setError(getString(R.string.error_invalid_account));
// focusView = mAccountView;
// cancel = true;
// }
if (cancel) {
focusView.requestFocus();
} else {
mAuthTask = new UserLoginTask(account, password);
mAuthTask.execute((Void) null);
}
}
private boolean isLengthValid(String text) {
return text.length() > 3;
}
public static void hideKeyboard(Activity activity) {
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
View view = activity.getCurrentFocus();
if (view == null) {
view = new View(activity);
}
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
private void startHomeActivity() {
Intent intent = new Intent(this, HomeActivity.class);
startActivity(intent);
}
public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {
private String mAccount;
private String mPassword;
UserLoginTask(String account, String password) {
mAccount = account;
mPassword = password;
}
@Override
protected Boolean doInBackground(Void... params) {
try {
// TODO: 帳號驗證
Thread.sleep(100);
} catch (InterruptedException e) {
return false;
}
return true;
}
@Override
protected void onPostExecute(final Boolean success) {
mAuthTask = null;
if (success) {
startHomeActivity();
} else {
mPasswordView.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
}
}
@Override
protected void onCancelled() {
mAuthTask = null;
}
}
}
package com.example.zxa01.iotclient.device;
package com.example.zxa01.iotclient.pojo;
public class Device {
private int id;
......
package com.example.zxa01.iotclient.pojo;
public class Setting {
private String key;
private String value;
public Setting(String key, String value) {
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
package com.example.zxa01.iotclient.setting;
import android.content.Context;
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 com.example.zxa01.iotclient.R;
/**
* A simple {@link Fragment} subclass.
* Activities that contain this fragment must implement the
* {@link SettingFragment.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {@link SettingFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class SettingFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public SettingFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment SettingFragment.
*/
// TODO: Rename and change types and number of parameters
public static SettingFragment newInstance(String param1, String param2) {
SettingFragment fragment = new SettingFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_setting, container, false);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onSettingFragment(uri);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onSettingFragment(Uri uri);
}
}
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<stroke
android:width="2dp"
android:color="@color/colorLighter" />
<solid android:color="@color/colorWhite" />
</shape>
</item>
<item
android:bottom="2dp">
<shape android:shape="rectangle">
<stroke
android:width="2dp"
android:color="@color/colorWhite" />
</shape>
</item>
</layer-list>
\ No newline at end of file
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
</vector>
<vector android:height="24dp" android:tint="#808080"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M15,9L9,9c-0.55,0 -1,0.45 -1,1v12c0,0.55 0.45,1 1,1h6c0.55,0 1,-0.45 1,-1L16,10c0,-0.55 -0.45,-1 -1,-1zM12,15c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2zM7.05,6.05l1.41,1.41C9.37,6.56 10.62,6 12,6s2.63,0.56 3.54,1.46l1.41,-1.41C15.68,4.78 13.93,4 12,4s-3.68,0.78 -4.95,2.05zM12,0C8.96,0 6.21,1.23 4.22,3.22l1.41,1.41C7.26,3.01 9.51,2 12,2s4.74,1.01 6.36,2.64l1.41,-1.41C17.79,1.23 15.04,0 12,0z"/>
</vector>
......@@ -2,5 +2,5 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/colorWhite" />
<corners android:radius="4dp" />
<corners android:radius="16dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<layout 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"
xmlns:tools="http://schemas.android.com/tools">
<android.support.constraint.ConstraintLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
......@@ -17,17 +19,20 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/navigation" />
app:menu="@menu/navigation"
/>
<FrameLayout
android:id="@+id/home_fragment_layout"
android:layout_width="match_parent"
android:layout_height="456dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/navigation"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</FrameLayout>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
</layout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/linear_login_form"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".login.LoginActivity">
<ScrollView
android:layout_width="282dp"
android:layout_height="487dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="@dimen/margin">
<TextView
android:layout_width="match_parent"
android:layout_height="62dp"
android:text="@string/login_iot_gateway"
android:textAlignment="center"
android:textSize="24sp" />
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/gateway"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_gateway"
android:inputType="text"
android:maxLines="1"
android:singleLine="true" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/account"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_account"
android:inputType="text"
android:maxLines="1"
android:singleLine="true" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_password"
android:imeActionId="6"
android:imeOptions="actionUnspecified"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true" />
</android.support.design.widget.TextInputLayout>
<Button
android:id="@+id/sign_in_button"
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/action_sign_in"
android:textStyle="bold" />
</LinearLayout>
</ScrollView>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
<layout 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">
<data>
<variable
name="viewModel"
type="com.example.zxa01.iotclient.home.device.DeviceViewModel"/>
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".device.DeviceFragment">
tools:context=".home.device.DeviceFragment">
<android.support.v7.widget.RecyclerView
android:id="@+id/device_recycler_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingTop="@dimen/padding"
android:clipToPadding="false"
tools:listitem="@layout/recycler_view_device" />
</FrameLayout>
\ No newline at end of file
<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/margin"
android:src="@drawable/ic_add_black_24dp"
app:backgroundTint="@color/colorPrimary"
/>
</FrameLayout>
</layout>
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".home.device.DeviceCreateFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorLighter"
android:fontFamily="monospace"
android:padding="@dimen/padding"
android:text="@string/title_device_create"
android:textAlignment="center"
android:textSize="@dimen/font" />
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/margin_sm"
android:hint="@string/input_placeholder"
android:padding="@dimen/padding_lg" />
</LinearLayout>
</FrameLayout>
</layout>
......@@ -3,7 +3,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".privacy.PrivacyFragment">
tools:context=".home.privacy.PrivacyFragment">
<TextView
android:layout_width="match_parent"
......
......@@ -3,11 +3,11 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".setting.SettingFragment">
tools:context=".home.setting.SettingFragment">
<TextView
<android.support.v7.widget.RecyclerView
android:id="@+id/setting_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
tools:listitem="@layout/recycler_view_setting" />
</FrameLayout>
\ No newline at end of file
<android.support.constraint.ConstraintLayout
android:id="@+id/device_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
<android.support.constraint.ConstraintLayout 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:id="@+id/device_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/margin_sm"
android:layout_margin="@dimen/margin"
android:layout_margin="@dimen/margin_sm"
android:background="@drawable/shadow"
android:elevation="2dp"
>
android:padding="@dimen/margin">
<ImageView
android:id="@+id/image_device"
android:layout_width="50dp"
android:layout_height="50dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@tools:sample/avatars" />
<ImageView
android:id="@+id/image_device"
android:layout_width="50dp"
android:layout_height="50dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:src="@drawable/ic_settings_remote_black_24dp"
tools:src="@tools:sample/avatars" />
<TextView
android:id="@+id/text_device_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="device name"
android:textSize="20sp"
android:textColor="@color/colorGray"
app:layout_constraintTop_toTopOf="@+id/image_device"
app:layout_constraintStart_toEndOf="@+id/image_device"
android:layout_marginStart="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="@+id/text_device_subtitle" />
<TextView
android:id="@+id/text_device_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginBottom="8dp"
android:textColor="@color/colorGray"
android:textSize="20sp"
app:layout_constraintBottom_toTopOf="@+id/text_device_subtitle"
app:layout_constraintStart_toEndOf="@+id/image_device"
app:layout_constraintTop_toTopOf="@+id/image_device"
tools:text="device name" />
<TextView
android:id="@+id/text_device_subtitle"
android:layout_width="285dp"
android:layout_height="20dp"
tools:text="subtitle"
app:layout_constraintBottom_toBottomOf="@+id/image_device"
app:layout_constraintStart_toEndOf="@+id/image_device"
android:layout_marginStart="8dp"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp"
app:layout_constraintHorizontal_bias="0.050" />
<TextView
android:id="@+id/text_device_subtitle"
android:layout_width="285dp"
android:layout_height="20dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="8dp"
app:layout_constraintBottom_toBottomOf="@+id/image_device"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.050"
app:layout_constraintStart_toEndOf="@+id/image_device"
tools:text="subtitle" />
<TextView
android:id="@+id/text_device_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
tools:text="connection"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/image_device" />
<TextView
android:id="@+id/text_device_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:textSize="12sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/image_device"
tools:text="connection" />
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#1DA1F2</color>
<color name="colorPrimary">#1da1f2</color>
<color name="colorPrimaryDark">#0D92E1</color>
<color name="colorAccent">#D81B60</color>
<color name="colorAccent">#7e7266</color>
<color name="colorGray">#2d2d2d</color>
<color name="colorLight">#808080</color>
<color name="colorLighter">#dadada</color>
<color name="colorWhite">#FFFFFF</color>
</resources>
<resources>
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="text_margin">16dp</dimen>
<dimen name="margin_lg">20dp</dimen>
<dimen name="margin">16dp</dimen>
<dimen name="margin_sm">8dp</dimen>
<dimen name="margin_xs">4dp</dimen>
<dimen name="padding_lg">20dp</dimen>
<dimen name="padding">16dp</dimen>
<dimen name="padding_sm">8dp</dimen>
<dimen name="padding_xs">4dp</dimen>
<dimen name="font_lg">24sp</dimen>
<dimen name="font">18sp</dimen>
<dimen name="font_sm">12sp</dimen>
</resources>
<resources>
<!--Home-->
<string name="app_name">IOTClient</string>
<string name="title_device">Device</string>
<string name="title_privacy">Privacy</string>
<string name="title_setting">Setting</string>
<string name="device_title">IOT Device</string>
<!--Create-->
<string name="title_device_create">Create New Device</string>
<string name="input_placeholder">the address of device</string>
<string name="button_qrcode">QRcode</string>
<string name="button_correct">Correct</string>
<string name="button_cancel">Cancel</string>
<!--Login-->
<string name="action_sign_in">Log in</string>
<string name="login_iot_gateway">Login to IOT gateway</string>
<string name="prompt_gateway">Gateway address</string>
<string name="prompt_account">Account</string>
<string name="prompt_password">Password</string>
<string name="error_invalid_gateway">This gateway format is not available</string>
<string name="error_invalid_account">This account is invalid</string>
<string name="error_invalid_password">This password is too short</string>
<string name="error_incorrect_password">This password is incorrect</string>
<string name="error_field_required">This field is required</string>
<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string>
<!--Common-->
<string name="dialog">dialog</string>
</resources>
......@@ -7,7 +7,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath 'com.android.tools.build:gradle:3.3.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
......
#Fri Apr 12 13:02:55 CST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment