Android 大项目仿微信项目实战
项目需求分析
- 实现微信的登录及注册功能
- 实现微信的界面左右滑屏及点击切换页面
- 实现微信的小部分功能
先看实现效果
Android 仿微信部分功能项目实战
实现登录注册界面
使用EditText让用户填写数据
点击Button注册按钮,传入数据并且跳转登录界面,要求用户将全部数据填写完成
使用SharedPreferences和Editor进行数据的存储
实现按钮点击事件将数据传入及intent跳转Activity
SharedPreferences sp = getSharedPreferences("SP", MODE_PRIVATE);
//存入数据
SharedPreferences.Editor editor = sp.edit();
re_register.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String username=reusername.getText().toString();
String country=recountry.getText().toString();
String userphone=reuserid.getText().toString();
String userpasswd=reuserpasswd.getText().toString();
if (username.isEmpty() && country.isEmpty() && userphone.isEmpty() && userpasswd.isEmpty()){
Toast.makeText(getApplicationContext(),"请将注册信息全部填写完成",Toast.LENGTH_LONG).show();
}else {
editor.putString("username",username);
editor.putString("country",country);
editor.putString("userphone",userphone);
editor.putString("userpasswd",userpasswd);
editor.commit();
Intent intent=new Intent();
intent.setClass(Bt_registerActivity.this,Bt_loginActivity.class);
startActivity(intent);
}
}
});
登录页面判断用户输入是否和存储的数据相同
tomain.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String userphone=sp.getString("userphone",null);
String userpasswd=sp.getString("userpasswd",null);
String lguserphone=lgphone.getText().toString();
String lguserpasswd=lgpasswd.getText().toString();
if (userphone.equals(lguserphone) && userpasswd.equals(lguserpasswd)){
Intent intent=new Intent();
intent.setClass(Bt_loginActivity.this,MainActivity.class);
startActivity(intent);
}else {
Toast.makeText(getApplicationContext(),"您未注册或者账号密码不正确",Toast.LENGTH_LONG).show();
}
主界面底部导航栏
给底部导航栏设置view pager滑屏和点击事件
导入view pager2的依赖包
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'androidx.viewpager2:viewpager2:1.0.0'
在xml中使用viewpager2标签 设置id
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
>
</androidx.viewpager2.widget.ViewPager2>
创建四个fragment页面添加到ArragList
创建适配器将ArragList添加进去
.registerOnPageChangeCallback实现 viewPager的滑动事件
changeTextColor() 自定义的方法 当滑动到对应fragment时底部导航栏的字体颜色、图标、顶部标题栏文字发送改变
viewPager.setCurrentItem(0);设置当前显示的页面
当点击底部导航栏的文字时也显示对应页面
ViewPager2 viewPager =findViewById(R.id.viewpager);
fragments = new ArrayList<>();
fragment_one=new Fragment_one();
fragment_two=new Fragment_two();
fragment_three=new Fragment_three();
fragment_four=new Fragment_four();
fragments.add(fragment_one);
fragments.add(fragment_two);
fragments.add(fragment_three);
fragments.add(fragment_four);
MyFragmentPagerAdapter pagerAdapter=new MyFragmentPagerAdapter(getSupportFragmentManager(),getLifecycle(),fragments); //确定适配进来的adapter有多少个
viewPager.setAdapter(pagerAdapter);
viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
changeTextColor(position);
wx.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
viewPager.setCurrentItem(0);
}
});
txl.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
viewPager.setCurrentItem(1);
}
});
fx.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
viewPager.setCurrentItem(2);
}
});
wd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
viewPager.setCurrentItem(3);
}
});
}
@Override
public void onPageScrollStateChanged(int state) {
super.onPageScrollStateChanged(state);
}
});
}
public void changeTextColor(int position){
switch (position){
case R.id.wx:
viewPager.setCurrentItem(0);
case 0:
wx.setTextColor(Color.parseColor("#FF03DAC5"));
txl.setTextColor(Color.parseColor("#FF000000"));
fx.setTextColor(Color.parseColor("#FF000000"));
wd.setTextColor(Color.parseColor("#FF000000"));
setTitle(titles[0]);
mimg1.setImageResource(R.drawable.wx_1);
mimg2.setImageResource(R.drawable.txl);
mimg3.setImageResource(R.drawable.fx);
mimg4.setImageResource(R.drawable.w);
break;
case R.id.txl:
viewPager.setCurrentItem(1);
case 1:
wx.setTextColor(Color.parseColor("#FF000000"));
txl.setTextColor(Color.parseColor("#FF03DAC5"));
fx.setTextColor(Color.parseColor("#FF000000"));
wd.setTextColor(Color.parseColor("#FF000000"));
setTitle(titles[1]);
mimg1.setImageResource(R.drawable.wx);
mimg2.setImageResource(R.drawable.txl_1);
mimg3.setImageResource(R.drawable.fx);
mimg4.setImageResource(R.drawable.w);
break;
case R.id.fx:
viewPager.setCurrentItem(2);
case 2:
wx.setTextColor(Color.parseColor("#FF000000"));
txl.setTextColor(Color.parseColor("#FF000000"));
fx.setTextColor(Color.parseColor("#FF03DAC5"));
wd.setTextColor(Color.parseColor("#FF000000"));
setTitle(titles[2]);
mimg1.setImageResource(R.drawable.wx);
mimg2.setImageResource(R.drawable.txl);
mimg3.setImageResource(R.drawable.fx_1);
mimg4.setImageResource(R.drawable.w);
break;
case R.id.wd:
viewPager.setCurrentItem(3);
case 3:
wx.setTextColor(Color.parseColor("#FF000000"));
txl.setTextColor(Color.parseColor("#FF000000"));
fx.setTextColor(Color.parseColor("#FF000000"));
wd.setTextColor(Color.parseColor("#FF03DAC5"));
setTitle(titles[3]);
mimg1.setImageResource(R.drawable.wx);
mimg2.setImageResource(R.drawable.txl);
mimg3.setImageResource(R.drawable.fx);
mimg4.setImageResource(R.drawable.w_1);
break;
}
用listview设置聊天界面和通讯录页面的数据
获取list view,和单个list_item中的ImageView和TextView的id
将list_item中图片资源和文字通过List<Map<String, Object>> 存放进去
创建SimpleAdapter适配器 将map中的数据适配
lv2 = view.findViewById(R.id.lv2);
int[] images = {R.mipmap.tjhy,R.mipmap.ql,R.mipmap.bq,R.mipmap.gzh,R.mipmap.dyh, R.mipmap.wxyd, R.mipmap.dyhxx,R.mipmap.tx1,R.mipmap.tx2,R.mipmap.tx3,R.mipmap.tx4};
String[] names1 = {"新的朋友","群聊","标签","公众号","订阅号", "微信团队", "订阅号消息","会飞的猪","QQ","近邻宝","携程旅游"};
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
for (int i = 0; i < images.length; i++) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("twoimg", images[i]);
map.put("twoname", names1[i]);
list.add(map);
}
adapter_two = new SimpleAdapter(getActivity(), list,
R.layout.fragment_two_item, new String[]{"twoimg", "twoname"},
new int[]{R.id.two_img, R.id.two_tv});
lv2.setAdapter(adapter_two);
发现页面设计功能
日期和时间的窗口控件
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
rq.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onCreateDialog(DATEDIA).show();
}
});
sj.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onCreateDialog(TIMEDIA).show();
}
});
}
protected Dialog onCreateDialog(int id) {
final Calendar calendar =Calendar.getInstance();
myear=calendar.get(Calendar.YEAR);
mmonth=calendar.get(Calendar.MONTH);
mday=calendar.get(Calendar.DAY_OF_MONTH);
switch (id){
case DATEDIA:
return new DatePickerDialog(getActivity(),mDateListener,myear,mmonth,mday);
case TIMEDIA:
return new TimePickerDialog(getActivity(),mTimeListener,mhour,mminute,false);
}
return null;
}
private DatePickerDialog.OnDateSetListener mDateListener= new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
myear = year;
mmonth = month;
mday = dayOfMonth;
}
};
private TimePickerDialog.OnTimeSetListener mTimeListener=new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
mhour=hourOfDay;
mminute=minute;
}
};
跳转视频号页面
简单使用了videoview 获取网路uri播放视频
videoView=findViewById(R.id.video);
videoView.setMediaController(new MediaController(this));
videoView.setVideoPath("https://stream7.iqilu.com/10339/upload_transcode/202002/18/20200218093206z8V1JuPlpe.mp4");
videoView.start();
朋友圈的发布和删除功能
pyqlist = new ArrayList<Map<String, Object>>();
for (int i = 0; i < pyq_tv1.length; i++) {
map = new HashMap<String, Object>();
map.put("pyq_img",pyq_img[i]);
map.put("time",pyq_time[i]);
map.put("pyq_tv1", pyq_tv1[i]);
map.put("pyq_tv2", pyq_tv2[i]);
pyqlist.add(map);
}
Collections.reverse(pyqlist);
pyqadapter=new SimpleAdapter(getApplicationContext(),pyqlist,R.layout.pyq_item,new String[]{"pyq_img","time","pyq_tv1", "pyq_tv2"},new int[]{R.id.pyq_img,R.id.pyq_time,R.id.pyqtv1, R.id.pyqtv2});
pyqlistview.setAdapter(pyqadapter);
pyqadd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Calendar calendar = Calendar.getInstance();
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
String time= hour+":"+minute;
int img=R.mipmap.wdtx;
String et2=pyq_et2.getText().toString();
if (et2.isEmpty()){
Toast.makeText(getApplicationContext(),"您需要输入文字才能发送哦!",Toast.LENGTH_LONG).show();
}else {
Collections.reverse(pyqlist);
map2=new HashMap<>();
map2.put("pyq_img",img);
map2.put("time",time);
map2.put("pyq_tv1", et1);
map2.put("pyq_tv2", et2);
pyqlist.add(map2);
Collections.reverse(pyqlist);
pyqlistview.setAdapter(pyqadapter);
}
}
});
AlertDialog.Builder builder=new AlertDialog.Builder(this);
pyqlistview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
Map<String, Object> map = pyqlist.get(arg2);
builder.setTitle("删除动态");
builder.setMessage("您真的要删除这条动态嘛");
builder.setPositiveButton("删除", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
pyqlist.remove(arg2);
pyqadapter.notifyDataSetChanged();// 更新列表数据
dialogInterface.cancel();
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
}
});
AlertDialog alertDialog =builder.create();
alertDialog.show();
}
});