本实验是用USB连接我的破手机(Vivo IQOO neo3)完成的,安卓版本几乎是最新的,所以实验报告中的代码有些过时的都已经修改,完全可以在最新版使用!
实验二 Android用户界面
一、实验目的
1.加深对用户界面的控件的理解和使用。
2.掌握各种界面布局的用法。
3.掌握选项菜单、子菜单和快捷菜单的使用方法。
二、实验内容
1.建立一个“ButtonDemo”的程序包含Button和ImageButton两个按钮上方是“Button按钮下方是一个ImageButton控件。
2.建立一个“CheckboxRadiobuttonDemo”程序包含五个控件,从上至下分别是TextView01、CheckBox01、CheckBox02、RadioButton01、RadioButton0,当选择RadioButton01,RadioButton02则无法选择?
3.建立一个“TabDemo”程序包含三个XML文件,分别为tab1.xml、tab2.xml和tab3.xml,这3个文件分别使用线性布局、相对布局和绝对布局示例中的main.xml的代码,并将布局的ID分别定义为layout01、lay out02和layout03
4.建立一个“MyContextMenu”程序,来完成Android菜单的功能。
三、实验仪器、设备
装有 Java JDK7.0 、 Android 、 Eclipse 等软件的微机
四、实验步骤
1.ButtonDemo
(1)MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
ImageButton imageButton = (ImageButton) findViewById(R.id.image_button);
button.setOnClickListener(this);
imageButton.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId())
{
case R.id.button:
Toast.makeText(MainActivity.this,"这是一个button",Toast.LENGTH_SHORT).show();
break;
case R.id.image_button:
Toast.makeText(MainActivity.this,"这是一个imageButton",Toast.LENGTH_SHORT).show();
break;
}
}
}
(2)activity_main.xml
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button"/>
<ImageButton
android:id="@+id/image_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher_foreground" />
</LinearLayout>
(3)实验步骤
点击button按钮,出现如下提示:
点击imageButton按钮,出现如下提示:
1.CheckboxRadiobuttonDemo
(1)MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private TextView textView011;
private TextView textView012;
private CheckBox checkBox01;
private CheckBox checkBox02;
private RadioButton radioButton01;
private RadioButton radioButton02;
private TextView textView02;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView011 = (TextView) findViewById(R.id.TextView011);
textView012 = (TextView) findViewById(R.id.TextView012);
textView02 = (TextView) findViewById(R.id.TextView02);
checkBox01 = (CheckBox) findViewById(R.id.CheckBox01);
checkBox02 = (CheckBox) findViewById(R.id.CheckBox02);
radioButton01 = (RadioButton) findViewById(R.id.RadioButton01);
radioButton02 = (RadioButton) findViewById(R.id.RadioButton02);
checkBox01.setOnClickListener(this);
checkBox02.setOnClickListener(this);
radioButton01.setOnClickListener(this);
radioButton02.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId())
{
case R.id.CheckBox01:
textView011.setText("checkBox 01 is checked?-" + String.valueOf(checkBox01.isChecked()));
break;
case R.id.CheckBox02:
textView012.setText("checkBox 02 is checked?-" + String.valueOf(checkBox02.isChecked()));
break;
case R.id.RadioButton01:
textView02.setText("RadioButton1 is selected");
break;
case R.id.RadioButton02:
textView02.setText("RadioButton2 is selected");
break;
}
}
}
(2)activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:id="@+id/TextView011"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="checkBox 01 is checked?-" />
<TextView
android:id="@+id/TextView012"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="checkBox 02 is checked?-" />
<CheckBox
android:id="@+id/CheckBox01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="CheckBox01" />
<CheckBox
android:id="@+id/CheckBox02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="CheckBox02" />
<TextView
android:id="@+id/TextView02"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<RadioGroup
android:id="@+id/RadioGroup01"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RadioButton
android:id="@+id/RadioButton01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="RadioButton01" />
<RadioButton
android:id="@+id/RadioButton02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="RadioButton02" />
</RadioGroup>
</LinearLayout>
(3)实验步骤
打开应用,随机点击checkbox和radiobutton,观察textview文字内容。同时可以观察到radiobutton01与radiobutton02不可以同时选择。
3.TabDemo采用了ViewPager2+ BottomNavigationView实现了比较新版本的导航栏切换
(1)MainActivity.java
public class MainActivity extends AppCompatActivity {
private BottomNavigationView bottomNavigationView;
private ViewPager2 viewPager2;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tabhost);
viewPager2 = findViewById(R.id.viewpager2bottom);
bottomNavigationView = findViewById(R.id.bootomnav2);
ViewPageAdapter myViewPager2BottomAdapter =
new ViewPageAdapter(this, initFragmentList());
viewPager2.setAdapter(myViewPager2BottomAdapter);
//设置 bottomNavigationView 的item 的点击事件 设置viewPager2的联动
bottomNavigationView.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
int itemId = item.getItemId();
switch (itemId) {
case R.id.liner:
viewPager2.setCurrentItem(0);
break;
case R.id.relative:
viewPager2.setCurrentItem(1);
break;
case R.id.absolute:
viewPager2.setCurrentItem(2);
break;
}
return true;
}
});
viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
switch (position) {
case 0:
bottomNavigationView.setSelectedItemId(R.id.liner);
break;
case 1:
bottomNavigationView.setSelectedItemId(R.id.relative);
break;
case 2:
bottomNavigationView.setSelectedItemId(R.id.absolute);
break;
}
}
});
}
private List<Fragment> initFragmentList() {
List<Fragment> fragmentList = new ArrayList<>();
fragmentList.add(new table1());
fragmentList.add(new table2());
fragmentList.add(new table3());
return fragmentList;
}
}
(2)tabhost.xml
<?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"
tools:context=".MainActivity">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewpager2bottom"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/bootomnav2"
/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bootomnav2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/viewpager2bottom"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/bottom_nav_menu"
app:labelVisibilityMode="labeled"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
(3)三个布局fragment
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id = "@+id/layout01"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="用户名:" >
</TextView>
<EditText android:id="@+id/entry"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:hint="线性布局">
</EditText>
<Button android:id="@+id/ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="确认">
</Button>
<Button android:id="@+id/cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="取消" >
</Button>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id = "@+id/layout02"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="用户名:" >
</TextView>
<EditText android:id="@+id/entry"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_below="@+id/label"
android:hint="相对布局">
</EditText>
<Button android:id="@+id/ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/entry"
android:text="确认">
</Button>
<Button android:id="@+id/cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/ok"
android:text="取消" >
</Button>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout xmlns:tools="http://schemas.android.com/tools"
android:id = "@+id/layout03"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
tools:ignore="Deprecated">
<TextView android:id="@+id/label"
android:layout_x="20dip"
android:layout_y="40dip"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:text="用户名:" >
</TextView>
<EditText android:id="@+id/entry"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_x="20dip"
android:layout_y="60dip"
android:hint="绝对布局">
</EditText>
<Button android:id="@+id/ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="20dip"
android:layout_y="100dip"
android:text="确认">
</Button>
<Button android:id="@+id/cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="20dip"
android:layout_y="150dip"
android:text="取消" >
</Button>
</AbsoluteLayout>
(4)fragment代码举例(table1为例)
public class table1 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.table1, null);
}
}
(5)实验步骤
切换三个布局,查看效果。
- MyContextMenu
(1)MainActivity.java
public class MainActivity extends Activity {
final static int CONTEXT_MENU_1 = Menu.FIRST;
final static int CONTEXT_MENU_2 = Menu.FIRST + 1;
final static int CONTEXT_MENU_3 = Menu.FIRST + 2;
TextView LabelView = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LabelView = (TextView) findViewById(R.id.label);
registerForContextMenu(LabelView);
}
@Override
public void onCreateContextMenu(ContextMenu menu,
View v, ContextMenu.ContextMenuInfo menuInfo) {
menu.setHeaderTitle("快捷菜单标题");
menu.add(0, CONTEXT_MENU_1, 0, "菜单子项1");
menu.add(0, CONTEXT_MENU_2, 1, "菜单子项2");
menu.add(0, CONTEXT_MENU_3, 2, "菜单子项3");
}
@Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case CONTEXT_MENU_1:
LabelView.setText("菜单子项1");
return true;
case CONTEXT_MENU_2:
LabelView.setText("菜单子项2");
return true;
case CONTEXT_MENU_3:
LabelView.setText("菜单子项3");
return true;
}
return false;
}
}
(2)activity_amin.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="@+id/label"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="hello" />
</LinearLayout>
(3)实验步骤
因为是要实现快捷菜单,所以长按手机屏幕可以呼出菜单。
五、实验思考题
1.建立一个程序 SpinnerDemo 包含 3 个子项 Spinner 控件
(1)MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Spinner spinner = (Spinner) findViewById(R.id.spinner);
List<String> list = new ArrayList<>();
list.add("学生信息");
list.add("计201");
list.add("李东");
list.add("205883");
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_dropdown_item_1line,list);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
}
}
(2)activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Ld_spinner_demo" />
<Spinner
android:id="@+id/spinner"
android:layout_width="300dip"
android:layout_height="wrap_content"/>
</LinearLayout>
(3)实验步骤
运行程序,并且点击。
2.建立一个 ListViewDemo 程序,包含四个控件,从上至下分别为 TextView01 、ListView01 、 ListView02 和 ListView03
(1)MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView textView = (TextView) findViewById(R.id.text_view_01);
ListView listView = (ListView) findViewById(R.id.list_view_01);
List<String> list = new ArrayList<>();
list.add("学校信息");
list.add("河北工业大学");
list.add("人工智能与数据科学学院");
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,list);
listView.setAdapter(adapter);
AdapterView.OnItemClickListener listViewListener = new AdapterView.OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
String msg = "父View:" + arg0.toString() + "\n"
+ "子View:" + arg1.toString() + "\n"
+ "位置:" + String.valueOf(arg2) + "\n"
+ "ID:" + String.valueOf(arg3) + "\n";
textView.setText(msg);
}
};
listView.setOnItemClickListener(listViewListener);
}
}
(2)activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:id="@+id/text_view_01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Ld_listView_demo" />
<ListView
android:id="@+id/list_view_01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ListView
android:id="@+id/list_view_02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ListView
android:id="@+id/list_view_03"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
(3)实验步骤
分别点击三个item,TextView中显示的内容有所变化。
3.AndroidAndroid界面框架是如何实现按键事件和触摸事件的?
(1)按键事件
当用户引发了按键事件后,过程通过调用onKey() 函数进行处理。如果界面控件设置了事件监听器,则事件将先传给监听器。如果没有设置,界面事件会直接传递给界面控件的其他事件处理函数。但即便设置了监听器,界面事件也可以再次传递给其他事件处理函数,这由处理函数的返回值决定。
(2)触摸事件
当用户引发了触摸事件后,过程通过调用 onTouch() 函数进行处理。函数通过对传入参数中MotionEvent调用getAction()函数获取类型,然后对不同触摸事件进行处理。过程也需要设置触摸监听器,并在函数中增加处理逻辑,比如获取坐标getX()、getY(),获取压力值getPressure(),获取接触点大小getSize()等等。一般触摸事件以ACTION_DOWN事件开始,经历0或者若干个ACTION_MOVE事件,以ACTION_UP结束。
六、实验感想
通过本次实验,我熟悉了各种基础控件和布局的使用方法。并尝试用fragment替代目前过时的tabhost来完成实验内容。了解了各种控件的监听和处理函数构成,并且成功使用函数完成了实验程序。最后归纳总结按键事件和触摸事件,让我对Android系统对事件的区别和处理上有了更加深刻的理解。