[Android学习] 1. 简易登录界面设计
Posted Yuxin X
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Android学习] 1. 简易登录界面设计相关的知识,希望对你有一定的参考价值。
通过对活动及控件的学习,今天制作一个简易登录界面。简要记录一下操作过程、遇到的问题及学到的经验,希望各位老师多多提出问题不吝赐教!
预期设计效果图
设计要求:
1.布局不限,参考上图;
2.利用EditText制作输入框,有语言提示;
3.登录注册忘记密码有跳转;
4.账号密码写死,登陆成功,密码错误用Toast or Dialog进行提示;
设计思路:
本次不使用Linear布局而采用更加可视化的Constraint布局,利用TextView作为标题文本框;两个EditText作为账号密码的输入框;三个Button按钮分别作为登录,注册,忘记密码;
设计代码:
//--------------------主活动布局段代码---------------------------//
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background"
tools:context=".MainActivity">
//------------------TextView:welcome----------------//
<TextView
android:id="@+id/textView"
android:layout_width="285dp"
android:layout_height="64dp"
android:gravity="center"
android:text="W E L C O M E"
android:textSize="35dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.124" />
//-----------------EditText:UserName-------------------//
<EditText
android:id="@+id/Edit_account"
android:layout_width="345dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:background="@drawable/edit_background"
android:gravity="center"
android:hint="请输入账号"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.342" />
//-----------------EditText:Password-------------------//
<EditText
android:id="@+id/Edit_password"
android:layout_width="344dp"
android:layout_height="52dp"
android:layout_gravity="center"
android:background="@drawable/edit_background"
android:gravity="center"
android:hint="请输入密码"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
//--------------------Button1:Login-------------------//
<Button
android:id="@+id/bn1"
android:layout_width="283dp"
android:layout_height="73dp"
android:layout_gravity="center"
android:background="@null"
android:outlineProvider="none"
android:text="登 录"
android:textSize="25dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.506"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.745" />
//--------------------Button2:Rollin-------------------//
<Button
android:id="@+id/bn2"
android:layout_width="91dp"
android:layout_height="33dp"
android:background="@null"
android:gravity="center"
android:text="注册账号"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.294"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.939" />
//--------------------Button3:ForgetPassWord-------------------//
<Button
android:id="@+id/bn3"
android:layout_width="97dp"
android:layout_height="34dp"
android:background="@null"
android:gravity="center"
android:text="忘记密码"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.709"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.94" />
</androidx.constraintlayout.widget.ConstraintLayout>
在写整个布局文件时,遇到很多问题:
1.在Contraint布局中,设计布局没问题,一运行整个布局乱飞,直接报下列错误。
This view is not constrained, it only has designtime positions, so it will jump to (0,0) unless you add constraints
解决:原因并未对控件设置约束,对控件四个边设计约束,一个是用布局下方的魔术棒(“infer Constrains)自动约束,这会导致控件乱飞使用少控件,或者每次插入先infer;其次就是将每个控件四个边连接到整个parent四个边上;
2.设置EditText文本框的样式、背景:
解决:在drawable文件夹下新建edit_background布局,在其中设置形状,四角弯曲度、颜色..;
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:shape="rectangle">
<solid
android:color="#efefef"/>
<corners
android:radius="8dp"/>
<stroke
android:width="2dp"
android:color="#505050"/>
</shape>
</item>
</layer-list>
在布局文件中将自定义文本框布局引入:android:background="@drawable/edit_background"
3. 设置Button按钮背景不透明;
解决:
1.在res/values/中找到两个theme文件,将其中这一行:
<style name="Theme.LoginInSystem" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
都改为:
<style name="Theme.LoginInSystem" parent="Theme.MaterialComponents.DayNight.DarkActionBar.Bridge">
之后对Button按钮布局文件中引入 android:background="@null"
主活动代码
//-----------------主活动代码--------------------------------//
package com.example.logininsystem;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity implements View.OnClickListener
//定义账号密码;
private String setaccount="123";
private String setpassword="123";
//定义控件对象;
private EditText username,password;
Button bn1,bn2,bn3;
Intent In1,In2,In3;
AlertDialog.Builder dialog;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.bn1).setOnClickListener(this);
findViewById(R.id.bn2).setOnClickListener(this);
findViewById(R.id.bn3).setOnClickListener(this);
username = findViewById(R.id.Edit_account);
password = findViewById(R.id.Edit_password);
@Override
public void onClick(View v)
switch(v.getId())
//登录成功跳转&&登陆失败警告!
case(R.id.bn1):
if(setaccount.equals(username.getText().toString())&&
setpassword.equals(password.getText().toString()))
In1 = new Intent(MainActivity.this,LogInSuccess.class);
startActivity(In1);
else
dialog = new AlertDialog.Builder(MainActivity.this);
dialog.setTitle("Warning");
dialog.setMessage("用户名密码错误,请重试!");
dialog.setCancelable(false);
dialog.setPositiveButton("确认", new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialog, int which)
);dialog.show();
break;
case(R.id.bn2):
In2 = new Intent(MainActivity.this,RollIn.class);
startActivity(In2);break;
case(R.id.bn3):
In3= new Intent(MainActivity.this,Forget.class);
startActivity(In3);break;
最终效果图:
自己做的第一个登陆界面,虽然只是一些简单的控件组合,但最终自己能搞出来还是很有成就感的,也算找个地方记录一下自己出现的问题以便未来的工作学习。
望共勉!
谢谢!
Android学习总结——强制下线功能(广播)
最近一口气买了好几本书,其中Android的《第一行代码》觉得真心不错,学到这个内容,顺便做个总结,加深印象。
强制下线的基本思想就是在界面上弹出一个对话框,让用户必须点击确定按钮跳转到登录界面,这里就有一个问题,通知强制下线时可能处于任何一个界面,我们总不能在每个界面都要实现弹出对话框的逻辑,所以这里可以利用广播来实现。
首先强制下线需要关闭所有活动,然后回到登录界面,所以我们这里创建一个ActivityCollector集合类来管理所有的活动,代码如下:
package com.example.xch.broadcastpractice;
import android.app.Activity;
import java.util.ArrayList;
import java.util.List;
/**
* Created by xch on 2016/12/15.
*/
public class ActivityCollector {
public static List<Activity> activityList=new ArrayList<Activity>();
//将Activity加入集合
public static void addActivity(Activity activity){
activityList.add(activity);
}
//将Activity移除集合
public static void removeActivity(Activity activity){
activityList.remove(activity);
}
//关闭所有Activity
public static void finishAll(){
for(Activity activity:activityList){
if(!activity.isFinishing()){
activity.finish();
}
}
}
}
然后创建BaseActivity类作为所有活动的父类:这个类继承自Activity,然后重写onCreate()方法调用ActivityCollector的addActivity()方法将当前正在创建的活动添加到活动管理器中,同理在onDestroy()中移除活动。
package com.example.xch.broadcastpractice;
import android.app.Activity;
import android.os.Bundle;
/**
* 作为所有活动的父类
* Created by xch on 2016/12/15.
*/
public class BaseActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityCollector.addActivity(this);//将Activity加入集合
}
@Override
protected void onDestroy() {
super.onDestroy();
ActivityCollector.removeActivity(this);//将Activity从集合移除
}
}
现在我们就可以随时随地将所有活动移除了。
下面我们模拟一个简单的登录功能,首先创建登录布局:activity_login.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.xch.broadcastpractice.LoginActivity"> <!-- Login progress --> <ProgressBar android:id="@+id/login_progress" style="?android:attr/progressBarStyleLarge" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:visibility="gone" /> <ScrollView android:id="@+id/login_form" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/email_login_form" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <android.support.design.widget.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <AutoCompleteTextView android:id="@+id/username" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/prompt_email" android:inputType="textEmailAddress" 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="@+id/login" android:imeActionLabel="@string/action_sign_in_short" android:imeOptions="actionUnspecified" android:inputType="textPassword" android:maxLines="1" android:singleLine="true" /> </android.support.design.widget.TextInputLayout> <Button android:id="@+id/login" style="?android:textAppearanceSmall" 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>
接下来编写登录界面的活动,新建LoginActivity继承自BaseActivity,代码如下:
package com.example.xch.broadcastpractice;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
/**
* Created by xch on 2016/12/15.
*/
public class LoginActivity extends BaseActivity {
private TextView usename;
private EditText password;
private Button login;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
usename= (TextView) findViewById(R.id.username);
password= (EditText) findViewById(R.id.password);
login= (Button) findViewById(R.id.login);
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String account=usename.getText().toString();
String pwd=password.getText().toString();
if(account.equals("xch_yang@126.com")&&pwd.equals("123456")){
Intent intent=new Intent(LoginActivity.this,MainActivity.class);
startActivity(intent);
finish();
}else{
Toast.makeText(LoginActivity.this,"用户名或密码错误!",Toast.LENGTH_SHORT).show();
}
}
});
}
}
这里直接使用一个默认值,如果登录成功就跳到MainActivity,否则就登录失败。所以我们在MainActivity中添加强制下线的功能。activity_main:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.xch.broadcastpractice.MainActivity"> <TextView android:text="恭喜你,登录成功!" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="119dp" android:layout_marginStart="119dp" android:layout_marginTop="15dp" android:id="@+id/textView" android:layout_alignParentTop="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" /> <Button android:text="强制下线" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="35dp" android:id="@+id/force_offline" android:layout_below="@+id/textView" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_marginLeft="105dp" android:layout_marginStart="105dp" /> </RelativeLayout>
MainActivity.class:
package com.example.xch.broadcastpractice;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends BaseActivity {
private Button force_offline;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
force_offline=(Button) findViewById(R.id.force_offline);
force_offline.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent("com.example.FORCE_OFFLINE");//发送广播,在广播接收器里实现强制下线的逻辑
sendBroadcast(intent);
}
});
}
}
这里很简单,就是在按钮事件里发送了一条广播,然后在广播接收器里实现强制下线的逻辑。接下来创建广播接收器ForceOfflineReceiver继承自Broadcast。
package com.example.xch.broadcastpractice;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.view.WindowManager;
/**
* Created by xch on 2016/12/15.
*/
public class ForceOfflineReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, Intent intent) {
//实现强制下线的逻辑
AlertDialog.Builder dialogBuilder=new AlertDialog.Builder(context);//使用AlertDialog.Builder构建一个对话框
dialogBuilder.setTitle("warning");
dialogBuilder.setMessage("你已经被强制下线,请重新登录");
dialogBuilder.setCancelable(false);//将对话框设置为不可取消
dialogBuilder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCollector.finishAll(); //销毁所有活动
Intent intent=new Intent(context,LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent); //重新启动登录界面
}
});
AlertDialog alertDialog=dialogBuilder.create();
//设置AlertDialog类型,保证在广播接收器中可以正常弹出
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alertDialog.show();
}
}
这里要注意的是,由于我们是在广播中启动活动LoginActivity,因此一定要给Intent加上FLAG_ACTIVITY_NEW_TASK标志。最后还要把对话框的类型设置成TYPE_SYSTEM_ALERT,不然它将无法在广播接受器中弹出。
接下来对AndroidManifest.xml进行配置:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.xch.broadcastpractice">
<!-- 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" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".LoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity"></activity>
<receiver android:name=".ForceOfflineReceiver">
<intent-filter>
<action android:name="com.example.FORCE_OFFLINE"/>
</intent-filter>
</receiver>
</application>
</manifest>
由于我们在广播接收器里弹出了一个系统级别的对话框,因此要声明权限:android.permission.SYSTEM_ALERT_WINDOW,最后别忘了注册广播ForceOfflineReceiver和活动LoginActivity。
运行程序,进入登录界面:
成功登录之后进入程序主界面:
点击强制下线按钮,就会发出一条强制下线的广播,广播接受器接收广播之后就会弹出提示框,用户点击确定之后就会重新回到登录界面:
以上是关于[Android学习] 1. 简易登录界面设计的主要内容,如果未能解决你的问题,请参考以下文章
简单步骤,使用 Android studio 实现保存 QQ 账号密码,和简易 QQ 用户登录界面