1 Activity
1.1 Activity之间的跳转
Intent intent = new Intent(MainActivity.this, MainActivity2.class);
startActivity(intent);
注:需要在manifest文件中添加<activity android:name=".MainActivity2"></activity>
1.2 Activity四种启动模式
- standard 标准的启动模式(默认) 每次启动这个activity的组件的时候, 都会去新创建 activity实例,然后放到任务栈中去。
从上图可以看出,Standard模式不管有没有该Activity,都会创建一个新的出来。
- singleTop 单一栈顶模式
在启动某个具体的activity 的时候,系统会去检查当前的任务栈中是否处于栈顶的当前的activity的实例,如果是,那么就不新创建。如果处于栈顶不是当前的activity的实例,那么仍然会新创建实例。如短信应用
从上图可以看出,在激活了Activity2后,不会再创建新的Activity2,因为已经有一个Activity2在任务栈的顶部了。如果在顶部的是Activity1,那么还是会继续创建Activity2的
- singleTask 单一任务栈模式
在启动activity的时候, 如果发现当前的任务栈中已经有这个activity的实例了,那么就不会新创建这个activity的实例了,并且会将处于这个activity 之上的activity的实例给弹栈。如果一个activity的实例创建的过程中,占用的内存比较大,消耗了挺多资源,那么 这个activity的启动模式通常就会设置成单一任务栈模式。例如:浏览器使用的是SingTask,浏览器中有js的解析器,CSS的解析器等等,设置成Singtask会节约内存
从上图可以看出,在激活了Activity1后,任务栈中只剩Activity1了,因为只能有Activity1一个实例,并且会将处于上面的Activity2给弹栈
- singleInstance 单一实例模式
如果某个activity的启动模式设置成单一实例模式,那么整个手机系统中,就只能有一个这个activity的实例了,并且这个activity的实例会在一个单独的任务栈中。这种启动一般很少用,除了系统级别的一些应用程序会用,其他的应用程序很少用。如果某个activity 要显示的界面在整个手机中只有一个的话,那么 这个activity就会设置成singleInstance。
从上图可以看出,在应用1要激活Activity3的时候,发现手机系统里的应用2已经有Activity3了,这时,应用1不会再去创建Activity3,而是共享应用2里的Activity3。
2 Android菜单创建和使用
2.1 OptionMenu(选项菜单)
2.1.1 如何使用OptionMenu
public boolean onCreateOptionsMenu(Menu menu) 调用OptionMenu,在这里完成菜单初始化
public boolean onOptionsItemSelected(MenuItem item) 菜单项被选中时触发,这里完成事件处理
public void onOptionsMenuClosed(Menu menu) 菜单关闭会调用该方法
public boolean onPrepareOptionsMenu(Menu menu) 选项菜单显示前会调用该方法,可在这里进行菜单的调整(动态加载菜单列表)
public boolean onMenuOpened(int featureId, Menu menu) 选项菜单打开以后会调用这个方法
2.1.2 案例
OptionsMenu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:title="保存"
android:id="@+id/save"/>
<item
android:title="设置"
android:id="@+id/setting"/>
<item
android:title="更多"
android:id="@+id/more">
<menu>
<item
android:title="帮助"
android:id="@+id/help"/>
<item
android:title="退出"
android:id="@+id/exit"/>
</menu>
</item>
</menu>
//创建OptionsMenu
@Override
public boolean onCreateOptionsMenu(Menu menu) {
//加载菜单资源
getMenuInflater().inflate(R.menu.optionmenu,menu);
return super.onCreateOptionsMenu(menu);
}
//OptionsMenu菜单项的选中方法
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.save:
Toast.makeText(this,"保存",Toast.LENGTH_SHORT).show();
break;
case R.id.setting:
Toast.makeText(this,"设置",Toast.LENGTH_SHORT).show();
break;
case R.id.help:
Toast.makeText(this,"帮助",Toast.LENGTH_SHORT).show();
break;
case R.id.exit:
finish();
break;
}
return super.onOptionsItemSelected(item);
}
2.2 ContextMenu(上下文菜单)
长按某个view不放,就会在屏幕中间弹出ContextMenu。
public class MainActivity extends AppCompatActivity {
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = findViewById(R.id.btn);
//1. 注册
registerForContextMenu(btn);
//2. 创建 覆盖onCreateContextMenu()方法
//3. 菜单项的操作 覆盖onContextItemSelected()方法
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
getMenuInflater().inflate(R.menu.contextmenu,menu);
super.onCreateContextMenu(menu, v, menuInfo);
}
//菜单项的操作
@Override
public boolean onContextItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.add:
Toast.makeText(this,"添加",Toast.LENGTH_SHORT).show();
break;
case R.id.delete:
Toast.makeText(this,"删除",Toast.LENGTH_SHORT).show();
break;
}
return super.onContextItemSelected(item);
}
2.3 PopupMenu(弹出式菜单)
在指定View下显示一个弹出菜单,而且他的菜单选项可以来自于Menu资源
Button btn2 = findViewById(R.id.btn2);
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//1.实例化PopupMenu对象 (参数2:被锚定的view)
PopupMenu popupMenu = new PopupMenu(MainActivity.this, btn2);
//2.加载菜单资源:利用MenuInflater将Menu资源加载到PopupMenu.getMenu()所返回的Menu对象中
//将R.menu.xx对于的菜单资源加载到弹出式菜单中
popupMenu.getMenuInflater().inflate(R.menu.popupmenu,popupMenu.getMenu());
//3.为PopupMenu设置点击监听器
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()){
case R.id.copy:
Toast.makeText(MainActivity.this,"复制",Toast.LENGTH_SHORT).show();
break;
case R.id.paste:
Toast.makeText(MainActivity.this,"粘贴",Toast.LENGTH_SHORT).show();
break;
}
return false;
}
});
//4.千万不要忘记这一步,显示PopupMenu
popupMenu.show();
}
});
3 Android对话框处理
3.1 提示对话框(AlertDialog)
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("提示");//标题
builder.setMessage("你确认退出程序吗?");//提示语
builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
builder.setNegativeButton("取消",null);
builder.show();//显示
/**
* builder.show(); 相当于下面两行代码
* AlertDialog dialog = builder.create();
* dialog.show();
*/
3.2 自定义对话框
自定义对话框步骤:
- 1.设计自定义对话框样式 ——> dialog_layout.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:background="@mipmap/dialog_bg"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="180dp"
android:text="你确认退出程序吗??"
android:textColor="#e61414"
android:textSize="25sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="@+id/btn_no"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@mipmap/no_btn" />
<Button
android:id="@+id/btn_yes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@mipmap/yes_btn" />
</LinearLayout>
</LinearLayout>
public class MyDialog extends Dialog {
public MyDialog(@NonNull Context context, int themeResId) {
super(context, themeResId);
//为对话框设置布局
setContentView(R.layout.dialog_layout);
findViewById(R.id.btn_no).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
findViewById(R.id.btn_yes).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
System.exit(0);
}
});
}
}
- 2.设计style(去掉标题栏、背景等)
<style name="MyDialog" parent="Theme.AppCompat.Dialog">
<item name="windowNoTitle">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
</style>
- 3.将第一步的布局应用到当前自定义对话框
setContentView(R.layout.dialog_layout);//为对话框设置布局
- 4.实例化对话框(参数1:环境上下文,参数2:第二步创建的style),并使用show()展示
MyDialog myDialog = new MyDialog(this,R.style.MyDialog);
myDialog.show();
3.3 PopupWindow(悬浮框,也叫弹窗)
3.3.1PopupWindow的使用步骤
- 1.准备弹窗所需的视图 popup_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00ffff"
android:orientation="horizontal"
android:padding="2dp">
<TextView
android:id="@+id/choose"
android:layout_width="60dp"
android:layout_height="30dp"
android:background="#000000"
android:gravity="center"
android:text="选择"
android:textColor="#ffffff" />
<View
android:layout_width="2dp"
android:layout_height="30dp"
android:background="#00ffff" />
<TextView
android:id="@+id/choose_all"
android:layout_width="60dp"
android:layout_height="30dp"
android:background="#000000"
android:gravity="center"
android:text="全选"
android:textColor="#ffffff" />
<View
android:layout_width="2dp"
android:layout_height="30dp"
android:background="#00ffff" />
<TextView
android:id="@+id/copy"
android:layout_width="60dp"
android:layout_height="30dp"
android:background="#000000"
android:gravity="center"
android:text="复制"
android:textColor="#ffffff" />
</LinearLayout>
View view = LayoutInflater.from(this).inflate(R.layout.popup_layout,null);
- 2.创建PopupWindow对象实例
参数1:用在弹窗中的view
参数2、参数3:弹窗的宽高
参数4:focusable,能否获取焦点
PopupWindow popupWindow = new PopupWindow(view, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT,true);
- 3.设置背景、注册事件监听器和添加动画
//设置背景、注册事件监听器和添加动画
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
//设置能响应外部的点击事件
popupWindow.setOutsideTouchable(true);
//设置能响应点击事件
popupWindow.setTouchable(true);
- 4.显示PopupWindow
参数1:锚(显示在哪个按钮或者视图下面)
参数2、参数3:相对于锚在x,y方向的偏移量
popupWindow.showAsDropDown(v,50,50);
- 5.为弹窗中的文本设置点击事件
//为弹窗中的文本设置点击事件
view.findViewById(R.id.choose).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"选择",Toast.LENGTH_SHORT).show();
popupWindow.dismiss();//控制弹窗消失
}
});
3.4 ArrayAdapter(数组适配器)
使用时具有局限性,默认情况下不支持imageview等非文本以外的内容,如果要显示的话需要重写getView方法。
3.4.1 基本使用
- 1.在布局文件中创建array_item_layout控件
<?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="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:gravity="center_vertical">
<ImageView
android:id="@+id/item_icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@mipmap/star"/>
<TextView
android:id="@+id/item_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"/>
</LinearLayout>
- 2.声明数据源
String[] items = {"Java","Android","HTML","Python"};
- 3.初始化适配器
ArrayAdapter adapter = new ArrayAdapter(this, R.layout.array_item_layout, R.id.item_txt, items);
- 4.绑定适配器
TextView textView = findViewById(R.id.item_txt);
textView.setAdapter(adapter);
3.4.2 案例
private void showArrayAdapter() {
final String[] items = {"Java","Android","HTML","Python"};
//参数1:环境上下文 参数2:布局资源索引 参数3:数据源
//ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_dropdown_item_1line, items);
//参数3:int textViewResourceId 指定文本需要放置布局中对应id文本控件的位置
ArrayAdapter adapter = new ArrayAdapter(this, R.layout.array_item_layout, R.id.item_txt,items);
AlertDialog.Builder builder = new AlertDialog.Builder(this)
.setTitle("请选择")
//参数1:适配器对象(对数据显示样式的规则制定器) 参数2:监听器
.setAdapter(adapter, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, items[which], Toast.LENGTH_SHORT).show();
dialog.dismiss();
}
});
builder.show();
}
最后
送福利了,现在关注我并且加入群聊可以获取包含源码解析,自定义View,动画实现,架构分享等。
内容难度适中,篇幅精炼,每天只需花上十几分钟阅读即可。
大家可以跟我一起探讨,欢迎加群探讨,有flutter—底层开发—性能优化—移动架构—资深UI工程师 —NDK相关专业人员和视频教学资料,还有更多面试题等你来拿
**扫描下方二维码免费领取