设计有什么可以改进或者不合理的地方,大家可以告诉博主哈。虚心接受建议!
这是一个安卓萌新做的第一个APP,本篇文章用来记录博主编写AS的步骤和一些细节。
这是最终实现效果:
http://player.youku.com/player.php/sid/XMzAyNTM1NDgzNg==/v.swf
xml界面的设计比较简单就不赘述了。
第一个难住博主的是在登陆Activity到注册Activity的信息交互。
在登陆界面使用startActivityForResult方法创造注册Activity,
这样可以在登陆界面实用使用onActivityResult在注册Activity结束的时候获取Intent中的数据。
设计逻辑是在登陆界面点击注册按钮时调用startActivityForResult方法创建一个结束可以取值的Activity
在onActivityResult中获取注册的账号和密码的值
以下是登陆Activity的源代码,mianfeizhuce_button跳转至注册Activity
startActivityForResult(Intent intent, int requestCode);
第一个参数:一个Intent对象,用于携带将跳转至下一个界面中使用的数据,使用putExtra(A,B)方法,此处存储的数据类型特别多,基本类型全部支持,也可以使用putExtra(Bundle)一般使用Bundle进行传输比较方便。
第二个参数:如果> = 0,当Activity结束时requestCode将归还在onActivityResult()中。以便确定返回的数据是从哪个Activity中返回,用来标识目标activity。
与下面的resultCode功能一致,感觉Android就是为了保证数据的严格一致性特地设置了两把锁,来保证数据的发送,目的地的严格一致性。
(2)onActivityResult(int requestCode, int resultCode,Intent data)
第一个参数:这个整数requestCode用于与startActivityForResult中的requestCode中值进行比较判断,是以便确认返回的数据是从哪个Activity返回的。
第二个参数:这整数resultCode是由子Activity通过其setResult()方法返回。适用于多个activity都返回数据时,来标识到底是哪一个activity返回的值。
第三个参数:一个Intent对象,带有返回的数据。可以通过data.getXxxExtra( );方法来获取指定数据类型的数据,
package com.learnandroid.youyou.imooc; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class denglu extends AppCompatActivity implements View.OnClickListener{ private Button dl,mfzc,zhmm; private EditText zh1,mm1; private int codetext=0; private String zh="000",mm="000";//默认账号密码 private String zh0="dsg3d2sfhgdh",mm0="gjkgjkg65kjg";//默认账号0 的账号名和密码 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.denglu); init(); Toast.makeText(this,"初始有账号密码都为000",Toast.LENGTH_SHORT).show(); } private void init(){ dl=(Button) findViewById(R.id.denglu_button); dl.setOnClickListener(this); mfzc=(Button) findViewById(R.id.mianfeizhuce_button); mfzc.setOnClickListener(this); zhmm=(Button) findViewById(R.id.zhaohuimima_button); zhmm.setOnClickListener(this); zh1=(EditText) findViewById(R.id.editText4); mm1=(EditText) findViewById(R.id.editText3); } @Override public void onClick(View view) { switch (view.getId()) { //登陆进入主界面按钮 case R.id.denglu_button: String zh2= zh1.getText().toString(); String mm2= mm1.getText().toString(); Intent intent=new Intent(this,MainActivity.class); if( mm.equals(mm2.toString()) && zh2.equals(zh.toString())) { startActivity(intent); } if( mm0.equals(mm2.toString()) && zh2.equals(zh0.toString())) { startActivity(intent); } else{ Toast.makeText(this,"密码错误",Toast.LENGTH_SHORT).show(); } break; //按钮按钮,点击后进入创建并注册Activity case R.id.mianfeizhuce_button: Intent intent1=new Intent(this,zhuce.class); startActivityForResult(intent1,codetext); break; case R.id.zhaohuimima_button: break; } } //注册界面关闭时的回调方法 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { zh0 = data.getStringExtra("zh"); mm0 = data.getStringExtra("mm"); zh1.setText(zh0); } }
以下是注册Activity的源代码
setResult(int resultcode,intent data)方法中
在意图跳转的目的地界面调用这个方法把Activity想要返回的数据返回到主Activity(在这里就是登陆Activity),
第一个参数:当Activity结束时resultCode将归还在onActivityResult()中,一般为RESULT_CANCELED , RESULT_OK该值默认为-1。
第二个参数:一个Intent对象,返回给主Activity的数据。在intent对象携带了要返回的数据,使用putExtra( )方法。
package com.learnandroid.youyou.imooc; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast;
public class zhuce extends AppCompatActivity implements View.OnClickListener{ private Button zhuce; private EditText zhanghao; private EditText mima; private String zh,mm; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_zhuce); zhuce=(Button) findViewById(R.id.zhuce_button); zhanghao=(EditText) findViewById(R.id.editText); mima=(EditText) findViewById(R.id.editText2); zhuce.setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.zhuce_button: zh=zhanghao.getText().toString(); mm=mima.getText().toString(); Toast.makeText(this,zh,Toast.LENGTH_SHORT).show(); Intent intent=new Intent(this,denglu.class); Bundle data=new Bundle(); data.putString("zh",zh); data.putString("mm",mm); intent.putExtras(data); this.setResult(0,intent); this.finish(); break; } } }
接下来就进入主界面MainActivity了其中包含一个RelativeLayout用来包含Fragment和一个菜单界面
而MainActivity底部的菜单按钮有选中的效果这是怎么回事呢?
原来是通过设置selector选择器来控制的,android:src="对于selector"即可。
比如说三个菜单中的主页Imageview
对其选中状态设置一张图片,未选中状态再设置一张图片。
在Java代码中对其相应ImageView对象中使用setSelected方法就可以对
state_selected的值进行改变了比如通过以下代码就可以在
三个ImageView被点击的时候改变state_selected的值了:
protected ImageView zy; protected ImageView wd; protected ImageView gw; void init(){ zy=(ImageView) this.findViewById(R.id.zhuye); wd=(ImageView) this.findViewById(R.id.wode); gw=(ImageView) this.findViewById(R.id.gouwu); zy.setOnClickListener(this); wd.setOnClickListener(this); gw.setOnClickListener(this); zy.setSelected(true); gw.setSelected(false); wd.setSelected(false); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); init(); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.zhuye: zy.setSelected(true); gw.setSelected(false); wd.setSelected(false); break; case R.id.wode: zy.setSelected(false); gw.setSelected(false); wd.setSelected(true); break; case R.id.gouwu: zy.setSelected(false); gw.setSelected(true); wd.setSelected(false); break; } }以下是主页ImageView的selector其他两个类似
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/indexa" android:state_selected="true"></item> <item android:drawable="@drawable/indexb" android:state_selected="false"></item> </selector>
主页设置好了之后就是要设置五个Fragment的设置了,主页Fragment,购物Fragment,我的Fragment,城市Fragment以及详情页Fragment。在进行点击事件时对Fragment进行hide,和show操作就能很好的控制各个Fragment的展示,达到视频中的效果。
在主页Fragment的界面设置中,
这个头部搜索框的形状设计也有讲究,初始的EditText形状是方形的
要使它变成椭圆的形状则需要一些小小的补充,那就是对background的设置
其中:
<corners //定义圆角
android:radius="dimension" //全部的圆角半径
android:topLeftRadius="dimension" //左上角的圆角半径
android:topRightRadius="dimension" //右上角的圆角半径
android:bottomLeftRadius="dimension" //左下角的圆角半径
android:bottomRightRadius="dimension" /> //右下角的圆角半径
Corners标签是用来字义圆角的,其中radius与其它四个并不能共同使用。
android:radius:定义四个角的的圆角半径。
其它四个是逐个字义每个角的圆角半径。
<EditText android:id="@+id/editText3" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="3" android:layout_marginBottom="5dp" android:layout_marginTop="5dp" android:background="@drawable/shape" android:gravity="center_horizontal" />
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <corners android:radius="100dp" /> <solid android:color="#ffffff" /> </shape>
剩下的Xml界面部分基本就没有什么难度了,只需要在Android Studio的Xml布局里面拖动控件就可以制作完成了。
比较麻烦的呢就是Fragment之间的交互,其中主要是主页Fragment和城市页Fragment的交互以及主页Fragment与详情页Fragment的交互。
在MainActivity主务必像如下将各个Fragment对象设置成全局公共的对象!!!!!
主页Fragment中的城市TextView也要设置成全局对象,因为在城市Fragment中要进行相应的setText操作。
public static zhuyeFragement ZYFragement=new zhuyeFragement(); public static chengshiFragment CSFragement=new chengshiFragment(); public static wodeFragment WDFragement=new wodeFragment(); public static gouwuFragment GWFragement=new gouwuFragment(); public static xiangqingFragment XQFragement=new xiangqingFragment();
因为在Fragment中调用的show和hide方法需要用到这几个Fragment对象,而且在Fragment中获取对象的方法和在Activity中有比较明显的不同,
Fragment也拥有相对应的生命周期,在Fragment被切换时会依次调用:onCreateView(),onActivityCreated(),onStart(),onResume()方法
按博主的理解在其中任何一个方法中都可以获取控件对象和对控件对象绑定监听器
而实际操作结果确实在onCreateView()中并不可以进行以上操作,而在onStart()方法中
可以进行以上操作,这一点其实博主并没有掌握到位,如果有看到这篇博客的观众们知道相应的解释请评论在下面,
万分感谢!
在获取控件对象时需要先getActivity获得Activity对象而不能像Activity中直接使用this,因为Fragment中的this是当前情况下的Fragment而不是Activity。
chengshi=(ImageView) getActivity().findViewById(R.id.chengshi_bt);
chengshi.setOnClickListener(this);
以下是主页Fragment的源代码
package com.learnandroid.youyou.imooc.fragment; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import com.learnandroid.youyou.imooc.MainActivity; import com.learnandroid.youyou.imooc.R; import com.learnandroid.youyou.imooc.fragment.*; public class zhuyeFragement extends Fragment implements View.OnClickListener{ ImageView chengshi; LinearLayout beef; public static TextView cs; @Override public void onStart() { cs=(TextView) getActivity().findViewById(R.id.chengshi); chengshi=(ImageView) getActivity().findViewById(R.id.chengshi_bt); chengshi.setOnClickListener(this); beef=(LinearLayout) getActivity().findViewById(R.id.L1); beef.setOnClickListener(this); super.onStart(); } @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.zhuyefragment,container,false); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.chengshi_bt: Toast.makeText(this.getContext(),"按钮中只有上海和北京有效",Toast.LENGTH_SHORT).show(); this.getActivity().getSupportFragmentManager() .beginTransaction() .hide(MainActivity.ZYFragement) .show(MainActivity.CSFragement) .hide(MainActivity.GWFragement) .hide(MainActivity.WDFragement) .hide(MainActivity.XQFragement) .commit(); break; case R.id.L1: Toast.makeText(this.getContext(),"跳转至详情页",Toast.LENGTH_SHORT).show(); this.getActivity().getSupportFragmentManager() .beginTransaction() .hide(MainActivity.ZYFragement) .hide(MainActivity.CSFragement) .hide(MainActivity.GWFragement) .hide(MainActivity.WDFragement) .show(MainActivity.XQFragement) .commit(); break; } } }其他几个部分的Fragment的设置基本没有什么太大的难度,Fragment之间的信息交互只需要通过全局对象就可以正常进行了。
这是博主Android领域制作的第一个小作品也是博主的第一篇博客,从学Java到Android开发只有短短2个月,如果有一些代码不符合逻辑的地方还请大家指出!谢谢!