说实话写了半年安卓了,我个人对intent的理解可能还是和刚入门那会一样,只会从这个activity跳到另一个,好在这次作业涉及到了这一方面,正好把这方面弥补一下。
先是实验的第一部分:
主页面
跳转到的页面
(设计到资源使用问题啊......Android Studio的话图片都是放在mipmap中的,如果使用其他编译器的同学发现报错的话就把图片路径改成你自己的,例如把mipmap修改为drawable。)
实验的要求就是点击第一个图中的任意一个列表项,然后可以跳转到对应的详情介绍页面中去。
先讲讲主页面的布局吧,代码如下:
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:layout_marginTop="20sp"
android:layout_marginStart="40sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="景点列表"
android:textColor="#000000"
android:textSize="30sp"/>
android:layout_marginStart="40sp"
android:layout_width="286dp"
android:layout_height="3sp"
android:background="#7CFC00" />
android:layout_marginTop="10sp"
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent">
(这部分没啥好讲的...)
由于使用到ListView控件,因此需要单独写一个xml页面,用于显示ListView中的每一个item项:
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:id="@+id/image_head"
android:layout_width="80sp"
android:layout_height="80sp"
android:layout_marginStart="10sp"
android:src="@mipmap/p1" />
android:id="@+id/scenery_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10sp"
android:text="黄山"
android:layout_marginStart="15dp"
android:layout_centerVertical="true"
android:layout_toEndOf="@+id/image_head" />
(要是toEndOf或者toStartOf这部分报错的话,就把End改成Right,Start改成Left。)
然后是对应布局的JAVA代码部分了:
首先列出总的代码文件吧,在下面再详细叙述具体作用:
(使用其他编译器的话把AppCompatActivity改为Activity)
public class MainActivity extends AppCompatActivity {
private String[] names = {"白云山","九寨沟","故宫博物院","黄山"};
private int[] headImagesSrc = {R.mipmap.p1,R.mipmap.p2,R.mipmap.p3,R.mipmap.p4};
ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView);
listView.setAdapter(new MyAdapter());
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
Intent intent = new Intent(MainActivity.this,ResultActivity.class);
intent.putExtra("position",position);
startActivity(intent);
}
});
}
class MyAdapter extends BaseAdapter{
@Override
public int getCount() {
return names.length;
}
@Override
public Object getItem(int position) {
return names[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = getLayoutInflater().inflate(R.layout.scenerylist_item,null);
ImageView headImage = (ImageView)view.findViewById(R.id.image_head);
headImage.setImageResource(headImagesSrc[position]);
TextView sceName = (TextView) view.findViewById(R.id.scenery_name);
sceName.setText(names[position]);
return view;
}
}
}
详述部分:
首先在代码文件的最开头我们private了两个数组,用于存储文本景点的名字以及图片的id(这里代码不再列出了);
然后,喜闻乐见的listView的初始化,然后是写适配器......这里我们由于使用到的ListView需要显示图片+文本内容,因此android自带的简单的适配器无法满足要求,因此我们自己另外再写一个适配器来满足这个要求:
(具体的讲解写在注释内)
class MyAdapter extends BaseAdapter{
@Override
public int getCount() {
//获取name数组的长度,此处为4
return names.length;
}
@Override
public Object getItem(int position) {
//根据position来返回相应的景点名字
return names[position];
}
@Override
public long getItemId(int position) {
//返回选中项的position值
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//获得我们自己定义的listView的item布局
View view = getLayoutInflater().inflate(R.layout.scenerylist_item,null);
//设置图片路径,根据position来显示图片
ImageView headImage = (ImageView)view.findViewById(R.id.image_head);
headImage.setImageResource(headImagesSrc[position]);
//根据position来设置景点名字
TextView sceName = (TextView) view.findViewById(R.id.scenery_name);
sceName.setText(names[position]);
return view;
}
}
然后是listView部分:
listView = (ListView) findViewById(R.id.listView);
listView.setAdapter(new MyAdapter());
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
Intent intent = new Intent(MainActivity.this,ResultActivity.class);
//intent传值,使用intent.putExtra来传输选中的位置的position给ResultActivity
intent.putExtra("position",position);
startActivity(intent);
}
});
这里使用了setOnItemClickListener方法达到了点击listView的每一个子项来进行跳转页面的功能;然后使用intent.putExtra方法来传递被选中的item的position值;
上述代码完成之后,启动模拟器的界面应该是这样的:
主界面
然后就是跳转到的界面辣:
我们先再创建一个Activity:
老规矩,我们先写一个layout布局文件:
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_horizontal">
android:id="@+id/sceName"
android:layout_marginTop="20sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="九寨沟"
android:textColor="#000000"
android:textSize="30sp"/>
android:layout_marginTop="20sp"
android:text="景点介绍"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:textColor="#000000"/>
android:layout_marginStart="40sp"
android:layout_width="wrap_content"
android:layout_height="3sp"
android:background="#7CFC00" />
android:id="@+id/sceImage"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10sp"
android:src="@mipmap/p1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
android:layout_width="match_parent"
android:layout_height="match_parent">
android:id="@+id/sceContext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10sp"
android:text="白云山有以白云峰、玉皇顶、小黄山、鸡角尖、千尺崖为代表的险峰奇石景观;以万亩原始林、唐代银杏林、野生牡丹园、高山杜鹃园、红桦林、白桦林、箭竹林为代表的森林景观;以黑龙潭、黄龙井、珍珠潭、青龙瀑布、白龙瀑布、九龙瀑布为代表的瀑潭景观;以白云洞、青蛇洞、锣鼓洞、洞天栈道、仙人桥为代表的洞窟景观;以乌曼寺、云岩寺、玉皇阁为代表的人文景观;以云海日出、盛夏避暑、金秋红叶为代表的物候景观。整个景区融山、石、水、洞、林、草、花、鸟、兽为一体,雄、险、奇、幽、美、妙交相生辉,既有北国山水雄伟之态,又有南方山水俏丽之容。
“仁者乐山,智者乐水。”位于洛阳嵩县的白云山,山亦雄,水亦俊。白云山国家森林公园地处八百里伏牛山腹地,景区内层峦叠嶂,险峰林立。海拔2216米的中原第一峰玉皇顶,是中原地区日出云海的最佳观赏点。
"/>
由于代码较多,因此简单叙述:
首先,为了防止TextView中的文字过多,我将显示景点详细介绍的TextView放入了一个ScrollView当中,达到了文字过多的时候,拖动文本可以实现滚动显示文字的效果;
然后,可以看到在最上面的一个TextView,我给他设置了一个id,因为跳转之后,相应的景点介绍名字也要改变,因此该textView需要获取之前一个activity传输过来的name,并将该name设置为显示的文本。
由于有读取资源文件的代码,使用Android Studio的同学需要先新建一个Assets文件夹,如下图:
如何新建一个assets文件夹
JAVA代码部分
public class ResultActivity extends AppCompatActivity {
private int[] sceImagesSrc = {R.mipmap.p1,R.mipmap.p2,R.mipmap.p3,R.mipmap.p4};
private String[] sceNames = {"白云山","九寨沟","故宫博物院","黄山"};
private String[] sceFile = {"t1.txt","t2.txt","t3.txt","t4.txt"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_result);
ImageView imageView = (ImageView) findViewById(R.id.sceImage);
TextView sceContext = (TextView) findViewById(R.id.sceContext);
TextView sceName = (TextView) findViewById(R.id.sceName);
Intent intent = getIntent();
int index = intent.getIntExtra("position",-1);
imageView.setImageResource(sceImagesSrc[index]);
sceName.setText(sceNames[index]);
String flag = readFromAssets(sceFile[index]);
sceContext.setText(flag);
}
public String readFromAssets(String fname){
String result = "";
try {
InputStream in = getResources().getAssets().open(fname);
byte[] buffer = new byte[in.available()];
in.read(buffer);
result = new String(buffer,"gbk");
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
}
代码详述:
先把使用到的资源文件放入一个数组中:
private int[] sceImagesSrc = {R.mipmap.p1,R.mipmap.p2,R.mipmap.p3,R.mipmap.p4};
private String[] sceNames = {"白云山","九寨沟","故宫博物院","黄山"};
private String[] sceFile = {"t1.txt","t2.txt","t3.txt","t4.txt"};
由于要实现读取assets文件夹中资源文件,因此我们写一个readFromAssets方法:
public String readFromAssets(String fname){
String result = "";
try {
//根据上述代码的sceFile[index]替换fname,实现打开对应的资源文件的功能
InputStream in = getResources().getAssets().open(fname);
byte[] buffer = new byte[in.available()];
in.read(buffer);
//设置文本文件格式为gbk
result = new String(buffer,"gbk");
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
其中fname的作用在下面讲到;
然后是比较重要的获得上一个activity传输的值的代码部分了:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_result);
ImageView imageView = (ImageView) findViewById(R.id.sceImage);
TextView sceContext = (TextView) findViewById(R.id.sceContext);
TextView sceName = (TextView) findViewById(R.id.sceName);
//获取上一个Activity传输过来的position值
Intent intent = getIntent();
//由于position是int类型的值,因此使用getIntExtra方法
int index = intent.getIntExtra("position",-1);
//根据获取到的值来显示对应的图片、文本
imageView.setImageResource(sceImagesSrc[index]);
sceName.setText(sceNames[index]);
String flag = readFromAssets(sceFile[index]);
//根据flag的值来使textView显示资源文件中的文本内容
sceContext.setText(flag);
}
至此,一个较为简单的跳转就实现了。
(如果你第二个activity是直接new一个class然后setContentView(layout)的话,建议你再到注册文件中去申明你写的class其实是要当Activity来使用的,不然使用intent会报错的。)
然后码云:https://gitee.com/bbchond/Android_Exp4_part1