微信主界面完整代码

Fragment+ViewPager实现

目录

前言

一、项目结构

二、使用步骤


前言

使用了ViewPager和Fragment的用法。支持滑屏显示界面和点击下标切换界面

一、项目结构

二、使用步骤

1.界面布局

主启动类MainActivityWithTab   测试类  MainActivity

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"><androidx.viewpager.widget.ViewPagerandroid:id="@+id/vp_main"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"tools:context=".MainActivity" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Buttonandroid:id="@+id/wechat"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="微信" /><Buttonandroid:id="@+id/btn_friend"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="通讯录" /><Buttonandroid:id="@+id/btn_find"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="发现" /><Buttonandroid:id="@+id/btn_mine"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="我" /></LinearLayout></LinearLayout>

activity_main_with_tab.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"><androidx.viewpager.widget.ViewPagerandroid:id="@+id/vp_main"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"tools:context=".MainActivity" /><Viewandroid:layout_width="match_parent"android:layout_height="1px"android:background="#aaaaaa"/><LinearLayoutandroid:background="#eeeeee"android:paddingTop="8dp"android:paddingBottom="8dp"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><com.itheima.myapplication.view.TabViewandroid:id="@+id/tab_wechat"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="微信" /><com.itheima.myapplication.view.TabViewandroid:id="@+id/tab_friend"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="通讯录" /><com.itheima.myapplication.view.TabViewandroid:id="@+id/tab_find"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="发现" /><com.itheima.myapplication.view.TabViewandroid:id="@+id/tab_mine"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="我" /></LinearLayout></LinearLayout>

fragment_tab.xml代码如下

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"tools:context=".fragment.TabFragment"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"tools:text="微信"android:textSize="30sp"android:textStyle="bold"android:id="@+id/tv_title"/></FrameLayout>

tab_view.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="wrap_content"android:layout_height="wrap_content"android:orientation="vertical"><FrameLayoutandroid:layout_gravity="center_horizontal"android:layout_width="wrap_content"android:layout_height="wrap_content"><ImageViewandroid:id="@+id/iv_icon"android:layout_width="wrap_content"android:layout_height="wrap_content"tools:src="@drawable/find" /><ImageViewandroid:id="@+id/iv_icon_select"android:layout_width="wrap_content"android:layout_height="wrap_content"tools:src="@drawable/find_select" /></FrameLayout><TextViewandroid:id="@+id/tv_title"android:textSize="20dp"android:textColor="@android:color/black"android:layout_gravity="center_horizontal"android:layout_width="wrap_content"android:layout_height="wrap_content"tools:text="微信"/>
</LinearLayout>

MainActivityWithTab代码如下

public class MainActivityWithTab extends AppCompatActivity {ViewPager mVpMain;private List<String> mTitles = new ArrayList<>(Arrays.asList("微信", "通讯录", "发现", "我"));TabView mBtnWeChat, mBtnFriend, mBtnFind, mBtnMine;private List<TabView> mTabs = new ArrayList<>();private SparseArray<TabFragment> mFraments = new SparseArray<>();private static final String BUNDLE_KEY_POS = "bundle_key_pos";private int mCurTabPos;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main_with_tab);if (savedInstanceState != null) {mCurTabPos =  savedInstanceState.getInt(BUNDLE_KEY_POS,0);}initViews();initViewPagerAdapter();initEvents();}/** 用来解决横竖屏切换时tab丢失的情况* */@Overrideprotected void onSaveInstanceState(@NonNull Bundle outState) {super.onSaveInstanceState(outState);outState.putInt(BUNDLE_KEY_POS, mVpMain.getCurrentItem());//存储当前的item}private void initViews() {mVpMain = findViewById(R.id.vp_main);mBtnWeChat = findViewById(R.id.tab_wechat);mBtnFriend = findViewById(R.id.tab_friend);mBtnFind = findViewById(R.id.tab_find);mBtnMine = findViewById(R.id.tab_mine);mBtnWeChat.setIconAndText(R.drawable.wechat, R.drawable.wechat_select, "微信");mBtnFriend.setIconAndText(R.drawable.friend, R.drawable.friend_select, "通讯录");mBtnFind.setIconAndText(R.drawable.find, R.drawable.find_select, "发现");mBtnMine.setIconAndText(R.drawable.mine, R.drawable.mine_select, "我");mTabs.add(mBtnWeChat);mTabs.add(mBtnFriend);mTabs.add(mBtnFind);mTabs.add(mBtnMine);//   mBtnWeChat.setProgress(1);//设置启动时微信页默认彩色//setCurrentTab(0);setCurrentTab(mCurTabPos);}private void setCurrentTab(int pos) {for (int i = 0; i < mTabs.size(); i++) {TabView tabView = mTabs.get(i);if (i == pos) {tabView.setProgress(1);} else {tabView.setProgress(0);}}}private void initViewPagerAdapter() {mVpMain.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {//  mVpMain.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager()){@NonNull@Overridepublic Fragment getItem(int position) {L.d("Fragment getItem position =" + position);TabFragment fragment = TabFragment.newInstance(mTitles.get(position));return fragment;}@Overridepublic int getCount() {return mTitles.size();}@NonNull@Overridepublic Object instantiateItem(@NonNull ViewGroup container, int position) {TabFragment fragment = (TabFragment) super.instantiateItem(container, position);mFraments.put(position, fragment);return fragment;}@Overridepublic void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {mFraments.remove(position);super.destroyItem(container, position, object);}});mVpMain.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {L.d("onPageScrolled position=" + position + "| positionOffset=" + positionOffset);if (positionOffset > 0) {//防止数组越界TabView left = mTabs.get(position);TabView right = mTabs.get(position + 1);left.setProgress((1 - positionOffset));right.setProgress(positionOffset);}}@Overridepublic void onPageSelected(int position) {L.d("onPageSelected position=" + position);}@Overridepublic void onPageScrollStateChanged(int arg0) {}});}private void initEvents() {for (int i = 0; i < mTabs.size(); i++) {TabView tabView = mTabs.get(i);final int finalI = i;tabView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mVpMain.setCurrentItem(finalI, false);//切换时没有动画,falsesetCurrentTab(finalI);}});}}
}

MainActivity代码如下:

public class MainActivity extends AppCompatActivity {ViewPager mVpMain;private List<String> mTitles = new ArrayList<>(Arrays.asList("微信", "通讯录", "发现", "我"));Button mBtnWeChat, mBtnFriend, mBtnFind, mBtnMine;private List<Button> mTabs = new ArrayList<>();private SparseArray<TabFragment> mFraments = new SparseArray<>();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);L.d("MainActivity onCreate");initViews();mVpMain = findViewById(R.id.vp_main);initViewPagerAdapter();}private void initViewPagerAdapter() {//   mVpMain.setOffscreenPageLimit(mTitles.size());/* (1)FragmentPagerAdapter 时滑动碎片*onDestroyView onCreateView 重走了*说明碎片没有被销毁 ,缓存起来了*(2)FragmentStatePagerAdapter 时滑动碎片* onDestroyView onDestroy* onCreateView onCreate* 重走了* 说明碎片被销毁重建,当用户滑走后返回需要重新加载数据** 总结:Tab大量时选择FragmentStatePagerAdapter,否则大量缓存消耗内存* Tab少量时选择FragmentPagerAdapter,* */mVpMain.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {//  mVpMain.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager()){@NonNull@Overridepublic Fragment getItem(int position) {L.d("Fragment getItem position =" + position);TabFragment fragment = TabFragment.newInstance(mTitles.get(position));if (position == 0) {fragment.setOnTitleClickListener(new TabFragment.OnTitleClickListener() {@Overridepublic void onClick(String title) {changeWeChatTab(title);}});}return fragment;}@Overridepublic int getCount() {return mTitles.size();}@NonNull@Overridepublic Object instantiateItem(@NonNull ViewGroup container, int position) {TabFragment fragment = (TabFragment) super.instantiateItem(container, position);mFraments.put(position, fragment);return fragment;}@Overridepublic void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {mFraments.remove(position);super.destroyItem(container, position, object);}});mVpMain.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {/*@param position  当前页面,及你点击滑动的页面*@param positionOffset 当前页面偏移的百分比* @param positionOffsetPixels 当前页面偏移的像素位置* */@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {L.d("onPageScrolled position=" + position + "| positionOffset=" + positionOffset);if (positionOffset>0){//防止数组越界Button left = mTabs.get(position);Button right = mTabs.get(position + 1) ;left.setText((1-positionOffset)+"");right.setText(positionOffset+"");}}//页面跳转完后得到调用方法,position是你当前选中的页面的Position@Overridepublic void onPageSelected(int position) {L.d("onPageSelected position=" + position);}/** 此方法是在状态改变的时候调用,其中arg0这个参数*有三种状态(0,1,2)。arg0 ==1的时辰默示正在滑动,arg0==2的时辰默示滑动完毕了,arg0==0的时辰默示什么都没做。*当页面开始滑动的时候,三种状态的变化顺序为(1,2,0)* */@Overridepublic void onPageScrollStateChanged(int arg0) {}});}private void initViews() {mBtnWeChat = findViewById(R.id.wechat);mBtnFriend = findViewById(R.id.btn_friend);mBtnFind = findViewById(R.id.btn_find);mBtnMine = findViewById(R.id.btn_mine);mTabs.add(mBtnWeChat);mTabs.add(mBtnFriend);mTabs.add(mBtnFind);mTabs.add(mBtnMine);mBtnWeChat.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {//调用Fragment的方法更改文字TabFragment tabFragment = mFraments.get(0);if (tabFragment != null) {tabFragment.changeTitle("微信 改变啦!!");}}});}//供fragment调用的方法public void changeWeChatTab(String title) {mBtnWeChat.setText(title);}
}

TabFragment代码如下

public class TabFragment extends Fragment {private static final String BUNDLE_KEY_TITLE = "key_title";private TextView mTvTitle;private String mTitle;/*作用:Fragment需要外界提供的title* bundle在应用的创建与销毁时保存数据* setArguments()方法可以获得* 如果用户切换应用界面后再返回,重新创建Fragment,默认会走无参构造,无法获取title* */public static TabFragment newInstance(String title) {Bundle bundle = new Bundle();bundle.putString(BUNDLE_KEY_TITLE, title);TabFragment tabFragment = new TabFragment();tabFragment.setArguments(bundle);return tabFragment;}@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);Bundle arguments = getArguments();//拿到外界的titleif (arguments != null) {mTitle = arguments.getString(BUNDLE_KEY_TITLE, "");//title赋值给TextView}L.d("onCreate,title =" + mTitle);}@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {L.d("onCreateView,title =" + mTitle);return inflater.inflate(R.layout.fragment_tab, container, false);}@Overridepublic void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {super.onViewCreated(view, savedInstanceState);mTvTitle = view.findViewById(R.id.tv_title);mTvTitle.setText(mTitle);//TextView展示titlemTvTitle.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {/*   //写法1.获取Activity对象MainActivity activity = (MainActivity) getActivity();activity.changeWeChatTab("微信changed");//写法2.获取Activity对象Activity activity2 =  getActivity();if (activity2 instanceof MainActivity){((MainActivity) activity2).changeWeChatTab("微信changed");}*///写法3if (mListener!=null){mListener.onClick("微信changed");}}});}@Overridepublic void onDestroyView() {super.onDestroyView();L.d("onDestroyView,title =" + mTitle);}@Overridepublic void onDestroy() {super.onDestroy();L.d("onDestroy,title =" + mTitle);}/*TabFragment加入到Activity中,即执行onCreateView()或onViewCreated()后* activity调用此方法才有意义* */public void changeTitle(String title) {if (!isAdded()) {return;}mTvTitle.setText(title);}public static interface OnTitleClickListener {void onClick(String title);}private OnTitleClickListener mListener;public void setOnTitleClickListener(OnTitleClickListener listener) {mListener = listener;}
}

工具类L类

/*** @author : this* @since : 2022/3/22* 作用:打印日志*/
public class L {private static final String TAG = "hyman";private static boolean sDebug = BuildConfig.DEBUG;/** @param  msg 打印的信息  args  Object数组* */public static void d(String msg,Object...args){if (!sDebug){return;}Log.d(TAG,String.format(msg,args));}
}

自定义控件TabView代码如下:

/*** @author : this* @since : 2022/3/23* 作用:自定义组合控件实现微信底栏*/
public class TabView extends FrameLayout {private ImageView mIvIcon, mIvIconSelect;private TextView mTvTitle;private static final int COLOR_DEFAULT = Color.parseColor("#ff000000");//黑色private static final int COLOR_SELECT = Color.parseColor("#ff45C01A");//绿色public TabView(@NonNull Context context, @Nullable AttributeSet attrs) {super(context, attrs);inflate(context, R.layout.tab_view, this);mIvIcon = findViewById(R.id.iv_icon);mIvIconSelect = findViewById(R.id.iv_icon_select);mTvTitle = findViewById(R.id.tv_title);setProgress(0);//默认灰色}//设置icon,text//方式一: 抽取自定义属性,通过xml设置//方式二:直接对外开放方法设置(推荐)public void setIconAndText(int icon,int iconSelect,String text){mIvIcon.setImageResource(icon);mIvIconSelect.setImageResource(iconSelect);mTvTitle.setText(text);}/** @param progress 透明度,0~1之间* */public void setProgress(float progress) {mIvIcon.setAlpha(1 - progress);mIvIconSelect.setAlpha(progress);mTvTitle.setTextColor(evaluate(progress, COLOR_DEFAULT, COLOR_SELECT));//文字颜色变化}/*** */public int evaluate(float fraction, int startValue, int endValue) {int startInt = (Integer) startValue;float startA = ((startInt >> 24) & 0xff) / 255.0f;float startR = ((startInt >> 16) & 0xff) / 255.0f;float startG = ((startInt >> 8) & 0xff) / 255.0f;float startB = (startInt & 0xff) / 255.0f;int endInt = (Integer) endValue;float endA = ((endInt >> 24) & 0xff) / 255.0f;float endR = ((endInt >> 16) & 0xff) / 255.0f;float endG = ((endInt >> 8) & 0xff) / 255.0f;float endB = (endInt & 0xff) / 255.0f;// convert from sRGB to linearstartR = (float) Math.pow(startR, 2.2);startG = (float) Math.pow(startG, 2.2);startB = (float) Math.pow(startB, 2.2);endR = (float) Math.pow(endR, 2.2);endG = (float) Math.pow(endG, 2.2);endB = (float) Math.pow(endB, 2.2);// compute the interpolated color in linear spacefloat a = startA + fraction * (endA - startA);float r = startR + fraction * (endR - startR);float g = startG + fraction * (endG - startG);float b = startB + fraction * (endB - startB);// convert back to sRGB in the [0..255] rangea = a * 255.0f;r = (float) Math.pow(r, 1.0 / 2.2) * 255.0f;g = (float) Math.pow(g, 1.0 / 2.2) * 255.0f;b = (float) Math.pow(b, 1.0 / 2.2) * 255.0f;return Math.round(a) << 24 | Math.round(r) << 16 | Math.round(g) << 8 | Math.round(b);}
}

find.png  find_select.png

wechat.png       wechat_select.png

friend.png          friend_select.png

mine.png        mine_select.png

慕课网高仿微信主界面完整代码相关推荐

  1. Android ActionBar应用实战,高仿微信主界面的设计

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/26365683 经过前面两篇文章的学习,我想大家对ActionBar都已经有一个相对 ...

  2. android仿微信聊天功能,Android高仿微信聊天界面代码分享

    微信聊天现在非常火,是因其界面漂亮吗,哈哈,也许吧.微信每条消息都带有一个气泡,非常迷人,看起来感觉实现起来非常难,其实并不难.下面小编给大家分享实现代码. 先给大家展示下实现效果图: OK,下面我们 ...

  3. php写的微信聊天界面,Android_Android高仿微信聊天界面代码分享,微信聊天现在非常火,是因其 - phpStudy...

    Android高仿微信聊天界面代码分享 微信聊天现在非常火,是因其界面漂亮吗,哈哈,也许吧.微信每条消息都带有一个气泡,非常迷人,看起来感觉实现起来非常难,其实并不难.下面小编给大家分享实现代码. 先 ...

  4. android 微信高仿,Android高仿微信聊天界面代码分享

    微信聊天现在非常火,是因其界面漂亮吗,哈哈,也许吧.微信每条消息都带有一个气泡,非常迷人,看起来感觉实现起来非常难,其实并不难.下面小编给大家分享实现代码. 先给大家展示下实现效果图: OK,下面我们 ...

  5. android 微信创建群ui,Android控件:高仿微信主UI

    高仿微信主UI 之前在Android组件:Fragment切换后保存状态 一文中讲到了Fragment切换后,是如何保存原来的状态的,最重要的就是用add方法取代现在各种教程常见的replace方法. ...

  6. 高仿微信聊天界面长按弹框样式

    效果图 背景 在公司做的项目里面,刚好有需要用到微信聊天界面长按弹框样式这种UI的. 网上找了一下,没找到. Android现成的 ListPopupWindow又不能满足需求. 因此在非上班时间撸一 ...

  7. java使用微信表情代码_iOS高仿微信表情输入功能代码分享

    最近项目需求,要实现一个类似微信的的表情输入,于是把微信的表情扒拉出来,实现了一把.可以从这里下载源码.看起来表情输入没有多少东西,不外乎就是用NSTextAttachment来实现图文混排,结果在实 ...

  8. 使用FragmentTabHost和ViewPager实现仿微信主界面侧滑

    最近看到很多界面主页都差不多,决定研究研究写出来,以后直接拿来用,不做代码的轮子,多总结,多学习 还是废话少说,先上图 介绍一下我的代码: 首先是布局文件: [html] view plaincopy ...

  9. 高仿微信聊天界面:基于CocoaAsyncSocket的即时通讯实现(IM 微信)

    Github地址:https://github.com/AlanZhangQ/Alan_cocoaSocket.git,如果有用,请点star. 之前做的项目有IM部分,在考虑了环信和融云等已经比较通 ...

最新文章

  1. 从技术细节看美团的架构
  2. Spring 3 MVC and XML example
  3. 4 个最好的 Linux 引导程序
  4. 大型高并发系统的系统设计要点
  5. python中使用正则模板匹配结果
  6. [转载] java避免空指针异常_第1部分:在现代Java应用程序中避免空指针异常
  7. 保利管道微服务1_.netcore 3.1高性能微服务架构:webapi规范
  8. Mybatis源码本地化构建Demo
  9. cad字体渐变_[AI10]透明渐变得问题 字体命令的一个变 pantone色系 AutoCAD2006中文版...
  10. 项目经理的软技能提升——知行合一
  11. servlet3.0理解
  12. 搭建Struts框架
  13. 修复win7开机很丑
  14. 【基础】光滑曲线什么意思?以及 n次方差、n次方和公式、二项式定理(和的n次方)
  15. 让我们一起来了解下代码复用法则
  16. linux生成相同文件名覆盖吗,去掉Linux中cp覆盖同名文件的提示
  17. 模糊查询like 如何查找 包含% 或者_的行
  18. word论文页码的设置(封面无编号、目录罗马数字和正文阿拉伯数字)
  19. python程序设计第二章序列类型 题库及选解
  20. LeetCode-1104. Path In Zigzag Labelled Binary Tree

热门文章

  1. 鸿蒙os相机,鸿蒙os有什么功能-有什么特殊之处
  2. 索尼z5p android 8,索尼良心!9款手机率先推送安卓8.0正式版
  3. 示例 PHP开发编译自己的拓展
  4. RSA加密 — 详解
  5. 职业培训之简历的写法
  6. linux下设置显示器对比度
  7. 你真的理解Java 字符串的不可变性吗?
  8. houdini vellum 显卡驱动造成解算崩溃笔记
  9. 京东智能店长主图长图功能怎么用?
  10. 常见的短视频拍摄手法分享