-
2020-06-29 23:03:44
实现效果
实现功能:
登陆界面含有用户名和密码,输入相应的内容,点击登陆按钮,系统获取输入框里面的内容,判断输入框是否与内容,没有输入则提示用户输入内容,然后判断输入的对应的用户名与密码是否存在于SharedPreference,如果存在则提示登陆成功,跳转页面,否则提示用户不存在。
xml文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <!--标题栏--> <include layout="@layout/main_title_bar"></include> <!--显示头像,记得加入id iv_head --> <ImageView android:id="@+id/iv_head" android:layout_width="100dp" android:layout_height="100dp" android:layout_marginTop="20dp" android:layout_gravity="center_horizontal" android:background="@drawable/touxiang"/> <!--输入框--> <EditText android:id="@+id/et_user_name" android:layout_width="fill_parent" android:layout_height="45dp" android:layout_marginTop="30dp" android:layout_marginLeft="60dp" android:layout_marginRight="60dp" android:layout_gravity="center_horizontal" android:drawableLeft="@drawable/name" android:drawablePadding="10dp" android:paddingLeft="8dp" android:gravity="center_vertical" android:hint="请输入用户名" android:singleLine="true" android:textColor="#204051" android:textColorHint="#a3a3a3" android:textSize="16sp"/> <!--输入框--> <EditText android:id="@+id/et_psw" android:layout_width="fill_parent" android:layout_height="45dp" android:layout_gravity="center_horizontal" android:layout_marginLeft="60dp" android:layout_marginRight="60dp" android:drawableLeft="@drawable/password" android:drawablePadding="10dp" android:paddingLeft="8dp" android:gravity="center_vertical" android:hint="请输入密码" android:inputType="textPassword" android:singleLine="true" android:textColor="#204051" android:textColorHint="#a3a3a3" android:textSize="16sp"/> <!--按钮--> <Button android:id="@+id/btn_login" android:layout_width="fill_parent" android:layout_height="50dp" android:layout_marginTop="35dp" android:layout_marginLeft="100dp" android:layout_marginRight="100dp" android:layout_gravity="center_horizontal" android:text="登 录" android:textColor="@android:color/white" android:color="@color/colorPrimary" android:textSize="18sp"/> <!--显示tv register , find_psw --> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginTop="35dp" android:layout_marginLeft="35dp" android:layout_marginRight="35dp" android:gravity="center_horizontal" android:orientation="horizontal"> <TextView android:id="@+id/tv_register" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="left" android:padding="8dp" android:text="立即注册" android:textColor="@android:color/darker_gray" android:textSize="12sp" /> <!--layout_weight="1" layout_width="0dp"实现均分效果--> <TextView android:id="@+id/tv_find_psw" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="right" android:padding="8dp" android:text="找回密码?" android:textColor="@android:color/darker_gray" android:textSize="12sp" /> </LinearLayout> </LinearLayout>
java文件:
LogonActivity.javapackage com.example.lsl.daily_note; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.ActivityInfo; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.text.TextUtils; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import android.graphics.Color; import android.graphics.drawable.Drawable; public class LogonActivity extends AppCompatActivity { private TextView tv_main_title;//标题 private TextView tv_register,tv_find_psw;//返回键,显示的注册,找回密码 private Button btn_login;//登录按钮 private String userName,psw,spPsw;//获取的用户名,密码,加密密码 private EditText et_user_name,et_psw;//编辑框 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); //设置此界面为竖屏 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); init(); // 登陆页面 // 设置姓名图标大小 EditText editName = (EditText) findViewById(R.id.et_user_name); Drawable name = getResources().getDrawable(R.drawable.name); name.setBounds(0, 0, 50, 50);//第一0是距左边距离,第二0是距上边距离,40分别是长宽 editName.setCompoundDrawables(name, null, null, null);//只放左边 // 设置密码图标大小 EditText editPassword = (EditText) findViewById(R.id.et_psw); Drawable password = getResources().getDrawable(R.drawable.password); password.setBounds(0, 0, 50, 50);//第一0是距左边距离,第二0是距上边距离,40分别是长宽 editPassword.setCompoundDrawables(password, null, null, null);//只放左边 // 设置按钮颜色 Button button = (Button) findViewById(R.id.btn_login); button.setBackgroundColor(Color.parseColor("#84a9ac")); } private void init() { //从main_title_bar中获取的id tv_main_title= (TextView) findViewById(R.id.tv_main_title); tv_main_title.setText("登录"); tv_register= (TextView) findViewById(R.id.tv_register); tv_find_psw= (TextView) findViewById(R.id.tv_find_psw); btn_login= (Button) findViewById(R.id.btn_login); et_user_name= (EditText) findViewById(R.id.et_user_name); et_psw= (EditText) findViewById(R.id.et_psw); //立即注册控件的点击事件 tv_register.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //为了跳转到注册界面,并实现注册功能 Intent intent=new Intent(LogonActivity.this,RegisterActivity.class); startActivityForResult(intent, 1); LogonActivity.this.finish(); } }); //找回密码控件的点击事件 tv_find_psw.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //跳转到找回密码界面(此页面暂未创建) } }); //登录按钮的点击事件 btn_login.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //开始登录,获取用户名和密码 getText().toString().trim(); userName=et_user_name.getText().toString().trim(); psw=et_psw.getText().toString().trim(); //对当前用户输入的密码进行MD5加密再进行比对判断, MD5Utils.md5( ); psw 进行加密判断是否一致 String md5Psw= MD5Utils.md5(psw); // md5Psw ; spPsw 为 根据从SharedPreferences中用户名读取密码 // 定义方法 readPsw为了读取用户名,得到密码 spPsw=readPsw(userName); // TextUtils.isEmpty if(TextUtils.isEmpty(userName)){ Toast.makeText(LogonActivity.this, "请输入用户名", Toast.LENGTH_SHORT).show(); return; }else if(TextUtils.isEmpty(psw)){ Toast.makeText(LogonActivity.this, "请输入密码", Toast.LENGTH_SHORT).show(); return; // md5Psw.equals(); 判断,输入的密码加密后,是否与保存在SharedPreferences中一致 }else if(md5Psw.equals(spPsw)){ //一致登录成功 Toast.makeText(LogonActivity.this, "登录成功", Toast.LENGTH_SHORT).show(); //保存登录状态,在界面保存登录的用户名 定义个方法 saveLoginStatus boolean 状态 , userName 用户名; saveLoginStatus(true, userName); //登录成功后关闭此页面进入主页 Intent data=new Intent(); //datad.putExtra( ); name , value ; data.putExtra("isLogin",true); //RESULT_OK为Activity系统常量,状态码为-1 // 表示此页面下的内容操作成功将data返回到上一页面,如果是用back返回过去的则不存在用setResult传递data值 setResult(RESULT_OK,data); //销毁登录界面 LogonActivity.this.finish(); //跳转到主界面,登录成功的状态传递到 MainActivity 中 startActivity(new Intent(LogonActivity.this, ItemDetailActivity.class)); return; }else if((spPsw!=null&&!TextUtils.isEmpty(spPsw)&&!md5Psw.equals(spPsw))){ Toast.makeText(LogonActivity.this, "输入的用户名和密码不一致", Toast.LENGTH_SHORT).show(); return; }else{ Toast.makeText(LogonActivity.this, "此用户名不存在", Toast.LENGTH_SHORT).show(); } } }); } /** *从SharedPreferences中根据用户名读取密码 */ private String readPsw(String userName){ //getSharedPreferences("loginInfo",MODE_PRIVATE); //"loginInfo",mode_private; MODE_PRIVATE表示可以继续写入 SharedPreferences sp=getSharedPreferences("loginInfo", MODE_PRIVATE); //sp.getString() userName, ""; return sp.getString(userName , ""); } /** *保存登录状态和登录用户名到SharedPreferences中 */ private void saveLoginStatus(boolean status,String userName){ //saveLoginStatus(true, userName); //loginInfo表示文件名 SharedPreferences sp=getSharedPreferences("loginInfo", MODE_PRIVATE); SharedPreferences sp=getSharedPreferences("loginInfo", MODE_PRIVATE); //获取编辑器 SharedPreferences.Editor editor=sp.edit(); //存入boolean类型的登录状态 editor.putBoolean("isLogin", status); //存入登录状态时的用户名 editor.putString("loginUserName", userName); //提交修改 editor.commit(); } /** * 注册成功的数据返回至此 * @param requestCode 请求码 * @param resultCode 结果码 * @param data 数据 */ @Override //显示数据, onActivityResult //startActivityForResult(intent, 1); 从注册界面中获取数据 //int requestCode , int resultCode , Intent data // LoginActivity -> startActivityForResult -> onActivityResult(); protected void onActivityResult(int requestCode, int resultCode, Intent data) { //super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data); if(data!=null) { //是获取注册界面回传过来的用户名 String userName = data.getStringExtra("userName"); if (!TextUtils.isEmpty(userName)) { //设置用户名到 et_user_name 控件 et_user_name.setText(userName); //et_user_name控件的setSelection()方法来设置光标位置 et_user_name.setSelection(userName.length()); } } } }
更多相关内容 -
Android记事本的实现
2019-01-08 16:25:23期末实现的android记事本小项目,能够正常运行,使用了Android自带的Sqlite数据库 -
android实现记事本app
2021-01-04 22:59:25自己写的一个简单的记事本app,效果如下: 一、首先是第一个界面的编写,最上面是一个TextView,中间是一个Linearlayout中嵌套一个listview布局,最下面是一个button。下面附上第一个页面的简单布局xml文件。 <... -
android做一个效果不一样的记事本?
2021-06-04 15:56:43如果想了解更多的android小功能,可以看一下我的其他博客博客地址去了解一下。这个功能效果还是比较好用的,给你带来不一样的体验,废话不多说。首先看效果,效果如下,可以不通过按图中的左滑等按钮,也可以使用...如果想了解更多的android小功能,可以看一下我的其他博客博客地址去了解一下。
这个功能效果还是比较好用的,给你带来不一样的体验,废话不多说。首先看效果,效果如下,可以不通过按图中的左滑等按钮,也可以使用手动滑动来效果:
mob8.gif
如果所示:
在这里插入图片描述
如果想了解框架源码的话,可以GitHub框架源地址去了解一下。
因为还有一个其他的功能,需要导入依赖包(例如:CardView,Snackbar等),如下所示:
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'com.google.android.material:material:1.2.1'
如果没有FloatingActionButton的话,可以去手动下载,我这里是下载好了:
在这里插入图片描述
2.layout的使用
1.在card.xml使用CardView来设置展示每个页面的内容
因为看起来来清晰一点,我只使用了一个TextView。
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="#FFFFFF"
card_view:cardCornerRadius="@dimen/card_corner_radius"
card_view:cardElevation="@dimen/elevation_large">
android:id="@+id/textViewCard"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="1"
android:background="@drawable/bg"
android:gravity="center"
android:text="@string/dummy_text"
android:textColor="#333"
android:textSize="30sp" />
效果如图:
在这里插入图片描述
2.在activity_main.xml调用框架swipestack框架使用滑动功能。
android:id="@+id/swipeStack"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/buttonSwipeLeft"
android:padding="@dimen/padding_swipestack"
app:stack_rotation="10"
app:stack_size="3" />
总体界面布局代码如下:
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:clipChildren="false"
tools:context=".MainActivity">
android:id="@+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="@color/colorPrimaryDark"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="记事本"
android:textColor="#FFF"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="60dp"
app:layout_constraintTop_toTopOf="parent">
android:id="@+id/buttonSwipeLeft"
style="?android:attr/borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:text="@string/swipe_left"
android:textSize="16sp" />
android:id="@+id/buttonSwipeRight"
style="?android:attr/borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:text="@string/swipe_right"
android:textSize="16sp" />
android:id="@+id/swipeStack"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/buttonSwipeLeft"
android:padding="@dimen/padding_swipestack"
app:stack_rotation="10"
app:stack_size="3" />
android:layout_width="match_parent"
android:layout_height="match_parent">
android:id="@+id/fabAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center"
android:layout_margin="@dimen/margin_fab"
android:src="@drawable/ic_content_add"
app:fabSize="normal" />
android:id="@+id/reflash"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="1dp"
android:onClick="Reflash"
app:layout_constraintBottom_toBottomOf="@+id/constraintLayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/reflash" />
效果如图所示:
在这里插入图片描述
3.MainActivity页面
1.初始化数据
private void fillWithTestData() {
mData.add("鹰击天风壮,鹏飞海浪春");
mData.add("做好手中事,珍惜眼前人");
mData.add("寒冷到了极致时,太阳就要光临");
mData.add("绝大多数人,在绝大多数时候");
}
2.点击事件实现左右滑动
@Override
public void onClick(View v) {
if (v.equals(mButtonLeft)) {
mSwipeStack.swipeTopViewToLeft(); //左滑动
} else if (v.equals(mButtonRight)) {
mSwipeStack.swipeTopViewToRight(); //右滑动
} else if (v.equals(mFab)) {
EditText(); //添加新数据
}
}
3.当进行左滑动,或右滑动的响应事件
//右滑动响应事件
@Override
public void onViewSwipedToRight(int position) {
String swipedElement = mAdapter.getItem(position);
Toast.makeText(this, getString(R.string.view_swiped_right, swipedElement),
Toast.LENGTH_SHORT).show();
}
//右滑动响应事件
@Override
public void onViewSwipedToLeft(int position) {
String swipedElement = mAdapter.getItem(position);
Toast.makeText(this, getString(R.string.view_swiped_left, swipedElement),
Toast.LENGTH_SHORT).show();
}
4.当页面为空时
@Override
public void onStackEmpty() {
Toast.makeText(this, R.string.stack_empty, Toast.LENGTH_SHORT).show();
}
5.重新刷新页面
public void Reflash(View v){
mSwipeStack.resetStack();
Snackbar.make(mFab, R.string.stack_reset, Snackbar.LENGTH_SHORT).show();
}
6.遍历mData数组里面所有的数据
public class SwipeStackAdapter extends BaseAdapter {
private List mData;
public SwipeStackAdapter(List data) {
this.mData = data;
}
@Override
public int getCount() {
return mData.size();
}
@Override
public String getItem(int position) {
return mData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.card, parent, false);
}
final TextView textViewCard = (TextView) convertView.findViewById(R.id.textViewCard);
textViewCard.setText(mData.get(position));
return convertView;
}
}
7.如果感觉分开看不是很清晰,可以看总体代码。
总体代码如下:
package com.example.cardtest1;
import androidx.appcompat.app.AppCompatActivity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import java.util.ArrayList;
import java.util.List;
import link.fls.swipestack.SwipeStack;
public class MainActivity extends AppCompatActivity implements SwipeStack.SwipeStackListener, View.OnClickListener {
private Button mButtonLeft, mButtonRight;
private FloatingActionButton mFab;
private ArrayList mData;
private SwipeStack mSwipeStack;
private SwipeStackAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSwipeStack = (SwipeStack) findViewById(R.id.swipeStack);
mButtonLeft = (Button) findViewById(R.id.buttonSwipeLeft);
mButtonRight = (Button) findViewById(R.id.buttonSwipeRight);
mFab = (FloatingActionButton) findViewById(R.id.fabAdd);
mButtonLeft.setOnClickListener(this);
mButtonRight.setOnClickListener(this);
mFab.setOnClickListener(this);
mData = new ArrayList<>();
mAdapter = new SwipeStackAdapter(mData);
mSwipeStack.setAdapter(mAdapter);
mSwipeStack.setListener(this);
fillWithTestData();
}
//数据初始化
private void fillWithTestData() {
mData.add("鹰击天风壮,鹏飞海浪春");
mData.add("做好手中事,珍惜眼前人");
mData.add("寒冷到了极致时,太阳就要光临");
mData.add("绝大多数人,在绝大多数时候");
}
//添加新的数据
public void EditText(){
final EditText inputServer = new EditText(MainActivity.this);
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("输入笔记").setIcon(R.drawable.book).setView(inputServer)
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
String text = inputServer.getText().toString();
mData.add(text.toString());
mAdapter.notifyDataSetChanged();
}
});
builder.show();
}
public void Reflash(View v){
mSwipeStack.resetStack();
Snackbar.make(mFab, R.string.stack_reset, Snackbar.LENGTH_SHORT).show();
}
//选择滑动方法,或者添加新数据
@Override
public void onClick(View v) {
if (v.equals(mButtonLeft)) {
mSwipeStack.swipeTopViewToLeft();
} else if (v.equals(mButtonRight)) {
mSwipeStack.swipeTopViewToRight();
} else if (v.equals(mFab)) {
EditText(); //添加新数据
}
}
@Override
public void onViewSwipedToRight(int position) {
String swipedElement = mAdapter.getItem(position);
Toast.makeText(this, getString(R.string.view_swiped_right, swipedElement),
Toast.LENGTH_SHORT).show();
}
@Override
public void onViewSwipedToLeft(int position) {
String swipedElement = mAdapter.getItem(position);
Toast.makeText(this, getString(R.string.view_swiped_left, swipedElement),
Toast.LENGTH_SHORT).show();
}
//数据为空时
@Override
public void onStackEmpty() {
Toast.makeText(this, R.string.stack_empty, Toast.LENGTH_SHORT).show();
}
//遍历mData里面的数据
public class SwipeStackAdapter extends BaseAdapter {
private List mData;
public SwipeStackAdapter(List data) {
this.mData = data;
}
@Override
public int getCount() {
return mData.size();
}
@Override
public String getItem(int position) {
return mData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.card, parent, false);
}
final TextView textViewCard = (TextView) convertView.findViewById(R.id.textViewCard);
textViewCard.setText(mData.get(position));
return convertView;
}
}
}
总体代码如上,如果遇到什么问题可以说出来,一起解决,因为为了展示起来方便一点,我没有把代码存入数据库,自己可以使用本地数据库或者bmob等原来存数据。
-
Android实现记事本项目
2020-05-18 15:32:12记事本界面包含内容列表和添加按钮。1、当长按列表条目(Item)时,会弹出一个提示是否删除Item的对话框,当点击对话框中的确定按钮时,删除Item,当点击对话框中的取消按钮时,取消删除Item。 2、当点击记事本界面... -
记事本界面
2019-01-09 15:38:16AndroidStudio登录界面 -
Android实现简易记事本
2021-01-06 00:55:26此次做的Android简易记事本的存储方式使用了SQLite数据库,然后界面的实现比较简单,但是,具有增删改查的基本功能,这里可以看一下效果图,如下: 具体操作就是长按可以删除操作,点击可以进行修改,点击添加... -
Android记事本开发之界面设计
2021-06-02 21:25:54不得不提一下ADT自带的手机截屏... main.xmlandroid:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent">android:layout_width="fill_parent"android:layout_height...不得不提一下ADT自带的手机截屏很方便,就在DDMS里可以找到。
main.xml
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
newdiary.xml
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="2dip"
android:text="@string/new_Title"
android:textColor="#FFFF00" />
android:id="@+id/text_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="2dip" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="2dip"
android:text="@string/new_Body"
android:textColor="#FFFF00" />
android:id="@+id/text_body"
android:layout_width="fill_parent"
android:layout_height="250dip"
android:layout_marginBottom="2dip"
android:gravity="top" />
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
android:id="@+id/new_save"
android:layout_width="80dip"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="50dp"
android:text="@string/new_saveButton"
android:textSize="20dip" />
android:id="@+id/new_cancel"
android:layout_width="80dip"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginLeft="50dp"
android:layout_toRightOf="@+id/new_save"
android:text="@string/new_cancelButton"
android:textSize="20dip" />
show_single_diary.xml
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@color/transparent"
android:orientation="vertical" >
android:id="@+id/simple_text_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="@color/red"
android:textSize="20sp" />
android:id="@+id/simple_text_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:textColor="@color/LightSlateGray" />
android:id="@+id/simple_text_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginBottom="1dip"
android:textColor="@color/LightSlateGray" />
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
android:id="@+id/simple_text_body"
android:layout_width="fill_parent"
android:layout_height="250dip"
android:layout_marginBottom="2dip"
android:gravity="top"
android:padding="1dip"
android:textColor="@color/yellow"
android:textSize="25sp" />
diary_item.xml
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
android:layout_width="fill_parent"
android:layout_height="match_parent">
android:layout_width="20dip"
android:layout_height="wrap_content"
android:gravity="center"
android:visibility="gone"
android:textColor="@color/red"
android:layout_alignParentLeft="true"
/>
android:layout_width="100dip"
android:layout_height="wrap_content"
android:textSize="20sp"
android:padding="1dip"
android:layout_margin="1dip"
android:gravity="center"
android:textColor="@color/red"
android:layout_alignParentLeft="true"
android:maxLines="1"
/>
android:textSize="14sp"
android:layout_margin="1dip"
android:padding="3dip"
android:textColor="@color/meadow_green"
android:layout_width="80dip"
android:gravity="center"
android:layout_alignParentRight="true"
android:layout_height="wrap_content"
android:maxLines="1"
/>
android:textSize="14sp"
android:textColor="@color/LightSlateGray"
android:layout_marginTop="2dip"
android:padding="1dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:paddingLeft="3dip"
android:paddingRight="10dip"
/>
-
Android示例程序剖析之记事本(二:Android菜单)
2021-05-26 13:05:22上一篇文章介绍了Android记事本示例程序一并进行了部分剖析,本文继续通过记事本来讲解几种Android菜单的使用。Android菜单简介Android提供了三种菜单类型,分别为选项菜单(options menu),上下文菜单(context menu)...上一篇文章介绍了Android记事本示例程序一并进行了部分剖析,本文继续通过记事本来讲解几种Android菜单的使用。
Android菜单简介
Android提供了三种菜单类型,分别为选项菜单(options menu),上下文菜单(context menu),子菜单(sub menu)。
options menu就是通过按home键来显示,context menu需要在view上按上2s后显示。这两种menu都有可以加入子菜单,子菜单不能种不能嵌套子菜单。options menu最多只能在屏幕最下面显示6个菜单选项,称为iconmenu,icon menu不能有checkable选项。多于6的菜单项会以more icon menu来调出,称为expanded menu。options menu通过activity的onCreateOptionsMenu来生成,这个函数只会在menu第一次生成时调用。任何想改变options menu的想法只能在onPrepareOptionsMenu来实现,这个函数会在menu显示前调用。onOptionsItemSelected 用来处理选中的菜单项。
context menu是跟某个具体的view绑定在一起,在Activity种用registerForContextMenu来为某个view注册context menu。context menu在显示前都会调用onCreateContextMenu来生成menu。onContextItemSelected用来处理选中的菜单项。
Android还提供了对菜单项进行分组的功能,可以把相似功能的菜单项分成同一个组,这样就可以通过调用setGroupCheckable,setGroupEnabled,setGroupVisible来设置菜单属性,而无须单独设置。
选项菜单(Options Menu)
Notepad中使用了options menu和context menu两种菜单。首先来看生成options menu的onCreateOptionsMenu函数。
menu.add(0, MENU_ITEM_INSERT, 0, R.string.menu_insert)
.setShortcut('3', 'a')
.setIcon(android.R.drawable.ic_menu_add);
这是一个标准的插入一个菜单项的方法,菜单项的id为MENU_ITEM_INSERT。有意思的是下面这几句代码:
Intent intent = new Intent(null, getIntent().getData());
intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0,
new ComponentName(this, NotesList.class), null, intent, 0, null);
这到底有何用处呢?其实这是一种动态菜单技术(也有点像插件机制),若某一个activity,其类型是”android.intent.category.ALTERNATIVE”,数据是”vnd.android.cursor.dir/vnd.google.note”的话,系统就会为这个activity增加一个菜单项。在androidmanfest.xml中查看后发现,没有一个activity符合条件,所以这段代码并没有动态添加出任何一个菜单项。
为了验证上述分析,我们可以来做一个实验,在androidmanfest.xml中进行修改,看是否会动态生成出菜单项。
实验一
首先我们来创建一个新的activity作为目标activity,名为HelloAndroid,没有什么功能,就是显示一个界面。
Java代码publicclassHelloAndroidextendsActivity {
@Override
protectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.main);
}
}
它所对应的布局界面XML文件如下:
XML/HTML代码<?xmlversion ="1.0"encoding="utf-8"?>
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
android:layout_width="fill_parent"
android:layout_height="wrap_content"android:id="@+id/TextView01"/>
然后修改androidmanfest.xml,加入下面这段配置,让HelloAndroid满足上述两个条件:
XML/HTML代码
好了,运行下试试,哎,还是没有动态菜单项加入呀!怎么回事呢?查看代码后发现,原来是onPrepareOptionsMenu搞的鬼!这个函数在onCreateOptionsMenu之后运行,下面这段代码中,由于Menu.CATEGORY_ALTERNATIVE是指向同一个组,所以把onCreateOptionsMenu中设置的菜单项给覆盖掉了,而由于onPrepareOptionsMenu没有给Menu.CATEGORY_ALTERNATIVE附新值,故Menu.CATEGORY_ALTERNATIVE还是为空。
Intent intent = new Intent(null, uri);
intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0, null, specifics, intent, 0,items);
好的,那我们暂时把上面这几句给注释掉,当然,也可以不注释这几句,在onCreateOptionsMenu中改groupid号,即将Menu.CATEGORY_ALTERNATIVE改为Menu.first,其他的也行,但注意不要改为menu.none,这样会覆盖掉。
menu.add(0, MENU_ITEM_INSERT, 0, R.string.menu_insert)
.setShortcut('3', 'a')
.setIcon(android.R.drawable.ic_menu_add);
添加的菜单。因为menu.none也为0。运行后就可以看到动态菜单出来了!
上面这个options menu是在NotesList界面上没有日志列表选中的情况下生成的,若先选中一个日志,然后再点“menu”,则生成的options menu是下面这样的:
哎,又动态增加了两个菜单项“Edit note”和”Edit title”,这又是如何动态加入的呢?这就是onPrepareOptionsMenu的功劳了。
Uri uri = ContentUris.withAppendedId(getIntent().getData(), getSelectedItemId());
首先获取选中的日志(若没有选择,则uri为空)
Intent[] specifics = new Intent[1];
specifics[0] = new Intent(Intent.ACTION_EDIT, uri);
MenuItem[] items = new MenuItem[1];
然后为选中的日志创建一个intent,操作类型为Intent.ACTION_EDIT,数据为选中日志的URI.于是会为选中的日志创建一个”Edit note”菜单项。
Intent intent = new Intent(null, uri);
intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0, null, specifics, intent, 0, items);
这几句和上面onCreateOptionsMenu函数中类似,用于动态增加菜单项,若某一个activity,其类型是”android.intent.category.ALTERNATIVE”,数据是”vnd.android.cursor.item/vnd.google.note”的话,系统就会为这个activity增加一个菜单项。在androidmanfest.xml中查看后发现,TitleEditor这个activity符合条件,于是系统就为TitleEditor这个activity动态添加一个菜单项”Edit title”。
else {
menu.removeGroup(Menu.CATEGORY_ALTERNATIVE);
}
若日志列表为空,则从菜单中删除组号为Menu.CATEGORY_ALTERNATIVE的菜单项,只剩下”Add note”菜单项。
处理“选中菜单项”事件
菜单项选中事件的处理非常简单,通过onOptionsItemSelected来完成,这里只是简单地调用startActivity(new Intent(Intent.ACTION_INSERT, getIntent().getData()));这个intent的操作类型为Intent.ACTION_INSERT,数据为日志列表的URI,即content:// com.google.provider.NotePad/notes。
Java代码@Override
publicbooleanonOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
caseMENU_ITEM_INSERT:
// Launch activity to insert a new item
startActivity(newIntent(Intent.ACTION_INSERT, getIntent().getData()));
returntrue;
}
returnsuper.onOptionsItemSelected(item);
}
上下文菜单(Context Menu)
下面介绍另一种菜单---上下文菜单,这通过重载onCreateContextMenu函数实现。首先确认已经选中了日志列表中的一个日志,若没选择,则直接返回。Cursor指向选中的日志项。
Java代码Cursor cursor = (Cursor) getListAdapter().getItem(info.position);
if(cursor ==null) {
// For some reason the requested item isn't available, do nothing
return;
}
然后,设置上下文菜单的标题为日志标题。
Java代码// Setup the menu header
menu.setHeaderTitle(cursor.getString(COLUMN_INDEX_TITLE));
最后为上下文菜单增加一个菜单项。
Java代码// Add a menu item to delete the note
menu.add(0, MENU_ITEM_DELETE,0, R.string.menu_delete);
对于上下文菜单项选中的事件处理,是通过重载onContextItemSelected实现的。
Java代码switch(item.getItemId()) {
caseMENU_ITEM_DELETE: {
// Delete the note that the context menu is for
Uri noteUri = ContentUris.withAppendedId(getIntent().getData(), info.id);
getContentResolver().delete(noteUri,null,null);
returntrue;
}
}
returnfalse;
对于日志的删除,首先调用ContentUris.withAppendedId(getIntent().getData(), info.id);来拼接出待删除日志的URI.然后getContentResolver().delete(noteUri, null, null);调用下层的Content Provider去删除此日志。
实验二
来做个简单实验,在上述代码基础上增加一个上下文菜单项。首先在onCreateContextMenu函数中增加一个上下文菜单项:
menu.add(0,MENU_ITEM_INSERT,0,R.string.menu_insert);
然后为其在onContextItemSelected函数中增加一个处理过程:
Java代码caseMENU_ITEM_INSERT:
{
newAlertDialog.Builder(this).setIcon(R.drawable.app_notes)
.setTitle(R.string.app_name).setMessage(R.string.error_message).setPositiveButton(R.string.button_ok,newOnClickListener(){
publicvoidonClick(DialogInterface dialog,intwhich) {
// TODO Auto-generated method stub
}
}).show();
returntrue;
}
实验结果如下:
2012年8月14日
-
android 记事本
2019-03-30 01:32:05NULL 博文链接:https://iaiai.iteye.com/blog/1323584 -
Android记事本.zip
2020-07-02 16:38:32Android记事本,有注册、登录、忘记密码界面,低端上滑界面(手机浏览器低端上滑界面相似),小型数据库存储。实现了记事本具有的功能,记事本可以实现追加功能等等。 -
Android 记事本
2019-05-24 10:45:00课余时间写完的记事本,主要是为了检验学习成果以及加深印象,主要用到知识的有: sqlite:用来存储数据 listview:item列表的展示 界面排版:如何让界面看起来好看点 效果 工程结构: 效果图 核心代码 主要是... -
安卓大作业 记事本升级版
2021-12-14 20:53:55记事本App(免积分下载),可以给记事本命名并且可以添加多个记事本,功能正常运行,界面美观,详情请看我的文章介绍,里面有运行的截图! -
Android记事本——记事本记事列表页实现
2020-06-29 23:18:45android:layout_width="30dp" android:layout_height="30dp" android:layout_alignParentBottom="true" android:layout_marginBottom="185dp" android:background="@drawable/up" android:layout_marginRight="6dp" ... -
阶段案例---记事本(Android)
2021-07-20 11:15:06一、搭建记事本页面布局 1.创建项目 创建一个名为Notepad的项目,Activity名称为NotepadActivity,布局文件名称为activity_notepad。 2.导入界面图片 3.放置界面控件 activity_notepad.xml布局文件 <?xml version... -
超级记事本基于设计论文
2021-06-10 11:55:17超级记事本基于设计论文基于Android的智能手机为人们提供了越来越多的应用功能。其中,使用智能手机进行一些日常的信息记录是最常用的功能之一。诸如日程安排、生活账单、重要提示信息等,以往单一功能的记事本已经... -
Android实现记事本功能
2021-01-20 09:14:52本文实例为大家分享了Android实现记事本功能的具体代码,供大家参考,具体内容如下 实现功能 1、文本数据的存储 2、图片数据存储 3、视频数据存储 4、自定义的Adapter 5、SQlite的创建 6、数据listview... -
android记事本app源码
2017-06-20 11:58:03这是一个关于开发一个android记事本类app的全部源代码,用到了qq登陆短信登陆等 -
安卓记事本:行客记事AndroidV1.9使用评测
2021-06-12 02:13:32行客记事安卓V1.9首发不久前,在2011百度“Web App应用创新大赛”中,行客记事凭借软件云应用的创新性,简洁的UI设计和程序的易用性获得大赛二等奖。之后也顺利的推出了多个平台的版本。如今的用户在使用智能手机时... -
Android记事本 (附apk和源码)
2021-04-28 16:01:33Android记事本 基于数据库工程下载功能简介操作演示部分代码展示 工程下载 apk下载点击跳转 工程下载点击跳转 功能简介 本项目是由Android Studio编写的一个安卓记事本软件,记事本功能包括——创建新笔记,查看笔记... -
android项目 之 记事本(1) ----- 界面设计
2014-09-06 09:30:26主要的界面有两个,分别 -
Android Studio实现记事本项目
2020-05-18 16:27:28手把手教你搭建一个记事本项目,简单又好用,经典之作。 -
android毕业设计,记事本,备忘录源码.zip
2020-05-26 20:51:35基于androidstudio开发的记事本,备忘录项目,附带apk安装文件与截图,以及源码。功能包括,新增,修改,删除,分页获取,设置界面,可根据自己的功能进行开发 -
android记事本实现——注册功能
2020-06-29 22:54:31实现效果: 主要功能 注册界面含有用户名和密码,确定密码三个输入框,输入相应的内容,点击注册按钮,系统获取输入框里面的内容,判断输入的密码与再次输入的... xml代码 <?xml version="1.0" encoding="utf-8"?... -
自己编写的Android记事本APP软件
2016-06-02 17:15:05自己使用ADT编写的一个简单的Android手机记事本的app,界面虽然简单,但都是一行一行代码码出来的 -
android记事本的设计报告,基于android记事本的设计与开发开题报告.doc
2021-06-03 06:13:46基于android记事本的设计与开发开题报告.doc太 原 科 技 大 学 华 科 学 院毕业设计开题报告学 生 姓 名学 号学 院、系 专 业论 文 题 目基于android的记事本的开发与设计指导教师 2014 年 11 月20日毕 业 设 计 开 ... -
Android项目之记事本
2020-06-20 18:31:15记事本界面包含内容列表和添加按钮。 1、当长按列表条目(Item)时,会弹出一个提示是否删除Item的对话框,当点击对话框中的确定按钮时,删除Item,当点击对话框中的取消按钮时,取消删除Item。 -
基于Android记事本软件设计与实现.ppt
2021-06-05 01:30:55基于Android记事本软件设计与实现START 基于Android记事本软件的设计与实现 研究现状 传统记事本虽然与纸质的笔记本相比,给我们的生产生活带来了巨大的便利,但随着智能化的迅猛发展和互联网的普及,人们对记事本的...