知识点

1.SelectRecyclerVie:RecycleView封装类,多选单选,同RecyclerView的用法一样

  • 效果图

    知识点
    文章图片
    image.png
第一步:导包:
compile 'cn.yc:YCRecycleViewLib:1.1'

第二步:设置适配器(注:适配器继承SelectRecyclerViewAdapter)
private void initRecycleView() { selectView.setLayoutManager(new GridLayoutManager(this, 4)); adapter = new SelectFollowAdapter(this, lists); selectView.setAdapter(adapter); //下划线 SpaceViewItemLine itemDecoration = new SpaceViewItemLine(SizeUtils.dp2px(5)); itemDecoration.setPaddingEdgeSide(false); itemDecoration.setPaddingStart(false); itemDecoration.setPaddingHeaderFooter(false); selectView.addItemDecoration(itemDecoration); }

2.CommonTabLayout: //导航栏,可用于主页的底部导航 (用ViewPager和CommonTabLayout实现底部导航)
  • 使用的额外方法
//commonTabLayout.showDot(1); //显示红点,参数代表哪个导航显示 //commonTabLayout.showMsg(1,1); //放qq、微信显示有几条未读信息,第一个参数是需要显示的底部位置,第二个蚕食是显示的条数 //commonTabLayout.setMsgMargin(1, 2, 2); //显示红点信息位置 //commonTabLayout.hideMsg(1); //隐藏未读消息,参数代表哪个导航隐藏

第一步:导包:
compile 'com.flyco.tablayout:FlycoTabLayout_Lib:2.1.0@aar'

第二步:布局引用

第三步:在res/values目录下新加arrays.xml文件,将首页底部导航的选中与未选择的图片和文字以分组的形式写进去
@drawable/tab_home_unselect @drawable/tab_speech_unselect @drawable/tab_contact_unselect @drawable/tab_more_unselect @drawable/tab_home_select @drawable/tab_speech_select @drawable/tab_contact_select @drawable/tab_more_select 首页 数据 工具 更多

第三步:定义实体类用于存放arrays xml中的资源: 【知识点】(实体类实现CustomTabEntity 接口)
public class TabEntity implements CustomTabEntity {public String title; public int selectedIcon; public int unSelectedIcon; public TabEntity(String title, int selectedIcon, int unSelectedIcon) { this.title = title; this.selectedIcon = selectedIcon; this.unSelectedIcon = unSelectedIcon; }@Override public String getTabTitle() { return title; }@Override public int getTabSelectedIcon() { return selectedIcon; }@Override public int getTabUnselectedIcon() { return unSelectedIcon; } }

第四步:获取arrays xml文件下的资源:
public ArrayList getTabEntity() { ArrayList mTabEntities = new ArrayList<>(); TypedArray mIconUnSelectIds = activity.getResources().obtainTypedArray(R.array.main_tab_un_select); TypedArray mIconSelectIds = activity.getResources().obtainTypedArray(R.array.main_tab_select); String[] mainTitles = activity.getResources().getStringArray(R.array.main_title); for (int i = 0; i < mainTitles.length; i++) { int unSelectId = mIconUnSelectIds.getResourceId(i, R.drawable.tab_home_unselect); int selectId = mIconSelectIds.getResourceId(i, R.drawable.tab_home_select); mTabEntities.add(new TabEntity(mainTitles[i],selectId , unSelectId)); } mIconUnSelectIds.recycle(); mIconSelectIds.recycle(); return mTabEntities; }

第五步:设置底部导航以及初始化ViewPager:
ArrayList mTabEntities = presenter.getTabEntity(); (CommonTabLayout)ctlTable.setTabData(mTabEntities);

/** * 初始化ViewPager数据 */ private void initViewPager() { List fragments = new ArrayList<>(); HomeFragment homeFragment = new HomeFragment(); FindFragment findFragment = new FindFragment(); DataFragment otherFragment = new DataFragment(); MeFragment meFragment = new MeFragment(); fragments.add(homeFragment); fragments.add(findFragment); fragments.add(otherFragment); fragments.add(meFragment); BasePagerAdapter adapter = new BasePagerAdapter(getSupportFragmentManager(), fragments); vpHome.setAdapter(adapter); vpHome.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { }@Override public void onPageSelected(int position) { ctlTable.setCurrentTab(position); }@Override public void onPageScrollStateChanged(int state) { } }); vpHome.setOffscreenPageLimit(4); vpHome.setCurrentItem(0); }

public class BasePagerAdapter extends FragmentPagerAdapter {private List mFragment; private List mTitleList; /** * 普通,主页使用 */ public BasePagerAdapter(FragmentManager fm, List mFragment) { super(fm); this.mFragment = mFragment; }/** * 接收首页传递的标题 */ public BasePagerAdapter(FragmentManager fm, List mFragment, List mTitleList) { super(fm); this.mFragment = mFragment; this.mTitleList = mTitleList; }@Override public Fragment getItem(int position) { return (Fragment) mFragment.get(position); }@Override public int getCount() { return mFragment.size(); }@Override public void destroyItem(ViewGroup container, int position, Object object) { super.destroyItem(container, position, object); }/** * 首页显示title,每日推荐等.. * 若有问题,移到对应单独页面 */ @Override public CharSequence getPageTitle(int position) { if (mTitleList != null) { return mTitleList.get(position); } else { return ""; } }public void addFragmentList(List fragment) { this.mFragment.clear(); this.mFragment = null; this.mFragment = fragment; notifyDataSetChanged(); }}

3.滑动卡片的效果
  • 效果图

    知识点
    文章图片
    image.png
第一步:导包:
compile 'cn.yc:YCCardViewLib:1.2'

第二步:布局文件

第三步:实现效果(pictures是图片地址集合)
private void initCardVioew(CardViewLayout cardView) { cardView.setAdapter(new CardViewLayout.Adapter() { @Override public int getLayoutId() { return R.layout.card_item; }@Override public void bindView(View view, int index) { ViewHolder holder = (ViewHolder) view.getTag(); if (holder == null) { holder = new ViewHolder(); holder.imageView = (ImageView) view.findViewById(R.id.image); view.setTag(holder); } if (pictures.size() > 0) { loadImgByPicassoWithRound(CardViewActivity.this, pictures.get(index), 6, R.mipmap.ic_launcher, holder.imageView); } }@Override public int getItemCount() { return pictures.size(); }class ViewHolder { ImageView imageView; } }); }

4.跑马灯效果(可以自动显示不同的标题) 知识点
文章图片
image.png 第一步:自定义view
public class MarqueeView extends ViewFlipper {private Context mContext; private List notices; private boolean isSetAnimDuration = false; private OnItemClickListener onItemClickListener; private int interval = 2000; private int animDuration = 500; private int textSize = 14; private int textColor = 0xffffffff; private boolean singleLine = false; private int gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL; private static final int TEXT_GRAVITY_LEFT = 0, TEXT_GRAVITY_CENTER = 1, TEXT_GRAVITY_RIGHT = 2; public MarqueeView(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs, 0); }private void init(Context context, AttributeSet attrs, int defStyleAttr) { this.mContext = context; if (notices == null) { notices = new ArrayList<>(); }TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.MarqueeViewStyle, defStyleAttr, 0); interval = typedArray.getInteger(R.styleable.MarqueeViewStyle_mvInterval, interval); isSetAnimDuration = typedArray.hasValue(R.styleable.MarqueeViewStyle_mvAnimDuration); singleLine = typedArray.getBoolean(R.styleable.MarqueeViewStyle_mvSingleLine, false); animDuration = typedArray.getInteger(R.styleable.MarqueeViewStyle_mvAnimDuration, animDuration); if (typedArray.hasValue(R.styleable.MarqueeViewStyle_mvTextSize)) { textSize = (int) typedArray.getDimension(R.styleable.MarqueeViewStyle_mvTextSize, textSize); textSize = px2sp(mContext, textSize); } textColor = typedArray.getColor(R.styleable.MarqueeViewStyle_mvTextColor, textColor); int gravityType = typedArray.getInt(R.styleable.MarqueeViewStyle_mvGravity, TEXT_GRAVITY_LEFT); switch (gravityType) { case TEXT_GRAVITY_CENTER: gravity = Gravity.CENTER; break; case TEXT_GRAVITY_RIGHT: gravity = Gravity.RIGHT | Gravity.CENTER_VERTICAL; break; } typedArray.recycle(); setFlipInterval(interval); }// 根据公告字符串启动轮播 public void startWithText(final String notice) { if (TextUtils.isEmpty(notice)) return; getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { getViewTreeObserver().removeGlobalOnLayoutListener(this); startWithFixedWidth(notice, getWidth()); } }); }// 根据公告字符串列表启动轮播 public void startWithList(List notices) { setNotices(notices); start(); }// 根据宽度和公告字符串启动轮播 private void startWithFixedWidth(String notice, int width) { int noticeLength = notice.length(); int dpW = px2dip(mContext, width); int limit = dpW / textSize; if (dpW == 0) { throw new RuntimeException("Please set MarqueeView width !"); } List list = new ArrayList(); if (noticeLength <= limit) { list.add(notice); } else { int size = noticeLength / limit + (noticeLength % limit != 0 ? 1 : 0); for (int i = 0; i < size; i++) { int startIndex = i * limit; int endIndex = ((i + 1) * limit >= noticeLength ? noticeLength : (i + 1) * limit); list.add(notice.substring(startIndex, endIndex)); } } notices.addAll(list); start(); }// 启动轮播 public boolean start() { if (notices == null || notices.size() == 0) return false; removeAllViews(); resetAnimation(); for (int i = 0; i < notices.size(); i++) { final TextView textView = createTextView(notices.get(i), i); final int finalI = i; textView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (onItemClickListener != null) { onItemClickListener.onItemClick(finalI, textView); } } }); addView(textView); }if (notices.size() > 1) { startFlipping(); } else { stopFlipping(); } return true; }private void resetAnimation(){ clearAnimation(); Animation animIn = AnimationUtils.loadAnimation(mContext, R.anim.anim_marquee_in); if (isSetAnimDuration) animIn.setDuration(animDuration); setInAnimation(animIn); Animation animOut = AnimationUtils.loadAnimation(mContext, R.anim.anim_marquee_out); if (isSetAnimDuration) animOut.setDuration(animDuration); setOutAnimation(animOut); }// 创建ViewFlipper下的TextView private TextView createTextView(CharSequence text, int position) { TextView tv = new TextView(mContext); tv.setGravity(gravity); tv.setText(text); tv.setTextColor(textColor); tv.setTextSize(textSize); tv.setSingleLine(singleLine); tv.setTag(position); return tv; }public int getPosition() { return (int) getCurrentView().getTag(); }public List getNotices() { return notices; }public void setNotices(List notices) { this.notices = notices; }public void setOnItemClickListener(OnItemClickListener onItemClickListener) { this.onItemClickListener = onItemClickListener; }public interface OnItemClickListener { void onItemClick(int position, TextView textView); }// 将px值转换为dip或dp值,保证尺寸大小不变 public int px2dip(Context context, float pxValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f); }// 将dip或dp值转换为px值,保证尺寸大小不变 public int dip2px(Context context, float dipValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dipValue * scale + 0.5f); }// 将px值转换为sp值,保证文字大小不变 public int px2sp(Context context, float pxValue) { final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; return (int) (pxValue / fontScale + 0.5f); }}

第二步:布局引用

第三步:设置适配
marqueeView.startWithList(list); (list是数据集合) //设置点击事件 marqueeView.setOnItemClickListener

5.阿里巴巴布局开源库VLayout(可以仿天猫淘宝的复杂布局)(mvp模式) 知识点
文章图片
image.png 可以参照这个文章https://www.jianshu.com/p/067abf64ed40
第一步:导包
compile('com.alibaba.android:vlayout:1.2.2@aar') { transitive = true }

第二步:view层:主要是写一个接口,接口中写需要更新ui的操作的方法
public interface IView { //设置轮播图 void setBanner(BannerView bannerView, Listpictures); //设置九宫格的点击 void setClick(int position); //设置跑马灯的点击 void setMarqueeClick(int position); //设置查看更多的点击 void setTitleMoreClick(int position); }

第三步:preserent层:定义一个接口,写需要初始化数据的操作方法;然后写一个实现类实现这个接口,重写相应方法,在具体方法中做相关请求数据的操作,同时在preserent的实现类中需要用构造方法将view引用过来,方便数据请求完后调用view接口的方法做更新ui的操作。
  • 接口
public interface IVPresenter { DelegateAdapter initRecycler( RecyclerView recyclerView); BaseAdapter initBanner(); BaseAdapter initGvMenu(); BaseAdapter initMarquee(); BaseAdapter initTitle(String title); }

  • 实现类
public class IVPresenterImpl implements IVPresenter { private IView iView; private Context context; public IVPresenterImpl(Context context, IView view) { this.iView = view; this.context = context; }/** * 获取DelegateAdapter */ @Override public DelegateAdapter initRecycler(RecyclerView recyclerView) { //创建VirtualLayoutManager VirtualLayoutManager virtualLayoutManager = new VirtualLayoutManager(context); recyclerView.setLayoutManager(virtualLayoutManager); //设置回收复用池大小(如果一屏内相同View个数比较多,需要设置一个合适的大小,放在来回滚动时重新创建view) RecyclerView.RecycledViewPool pool = new RecyclerView.RecycledViewPool(); recyclerView.setRecycledViewPool(pool); pool.setMaxRecycledViews(0, 20); //设置适配器 DelegateAdapter delegateAdapter = new DelegateAdapter(virtualLayoutManager, true); recyclerView.setAdapter(delegateAdapter); return delegateAdapter; }/** * 初始化轮播图 */ @Override public BaseAdapter initBanner() { final List icons = new ArrayList<>(); icons.add("http://pic4.nipic.com/20091217/3885730_124701000519_2.jpg"); icons.add("http://img.zcool.cn/community/01711b59426ca1a8012193a31e5398.gif"); icons.add("http://img.taopic.comhttp://img.readke.com/120727/201995-120HG1030762.jpg"); icons.add("http://img.zcool.cn/community/0142135541fe180000019ae9b8cf86.jpg@1280w_1l_2o_100sh.png"); icons.add("http://news.cnhubei.com/ctjb/ctjbsgk/ctjb40/200808/W020080822221006461534.jpg"); icons.add("http://img.zcool.cn/community/01fd6756f3f8c732f875a944272b7b.jpg"); return new BaseAdapter(new LinearLayoutHelper(), 1, R.layout.banner, this, context, 1) { @Override public void onBindViewHolder(BaseViewHolder holder, int position) { super.onBindViewHolder(holder, position); //绑定数据 BannerView bannerView = holder.getView(R.id.banner); iView.setBanner(bannerView, icons); } }; }/** * 初始化九宫格 * * @return */ @Override public BaseAdapter initGvMenu() { final List imagers = new ArrayList<>(); TypedArray iconArraty = context.getResources().obtainTypedArray(R.array.gv_menu); final String[] textArray = context.getResources().getStringArray(R.array.text); for (int i = 0; i < textArray.length; i++) { imagers.add(iconArraty.getResourceId(i, R.mipmap.ic_category_2)); } iconArraty.recycle(); GridLayoutHelper gridLayoutHelper = new GridLayoutHelper(4); gridLayoutHelper.setPadding(0, 16, 0, 16); gridLayoutHelper.setVGap(16); //控制子元素之间的垂直间距 gridLayoutHelper.setHGap(0); //控制子元素之间的水平间距 gridLayoutHelper.setBgColor(Color.WHITE); return new BaseAdapter(gridLayoutHelper, imagers.size(), R.layout.gv_item, this, context, 2) { @Override public void onBindViewHolder(BaseViewHolder holder, final int position) { super.onBindViewHolder(holder, position); holder.setBackgroundRes(R.id.circle_image, imagers.get(position)); holder.setText(R.id.text, textArray[position]); LinearLayout ll = holder.getView(R.id.ll); ll.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { iView.setClick(position); } }); } }; }/** * 初始化跑马灯效果 * * @retur */ @Override public BaseAdapter initMarquee() { final List titles = new ArrayList<>(); titles.add("1.坚持读书,写作,源于内心的动力!"); titles.add("2.欢迎订阅喜马拉雅听书!"); return new BaseAdapter(new LinearLayoutHelper(), 1, R.layout.marquee, this, context, 3) { @Override public void onBindViewHolder(BaseViewHolder holder, final int position) { super.onBindViewHolder(holder, position); MarqueeView marqueeView = holder.getView(R.id.marqueeView); marqueeView.startWithList(titles); marqueeView.setOnItemClickListener(new MarqueeView.OnItemClickListener() { @Override public void onItemClick(int position, TextView textView) { iView.setMarqueeClick(position); } }); } }; }/** * 初始化标题 * * @return */ @Override public BaseAdapter initTitle(final String title) {return new BaseAdapter(new LinearLayoutHelper(), 1, R.layout.title, this, context, 4) { @Override public void onBindViewHolder(BaseViewHolder holder, final int position) { super.onBindViewHolder(holder, position); holder.setText(R.id.title, title); holder.getView(R.id.more).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { iView.setTitleMoreClick(position); } }); } }; }

第四步:activity做更新ui的操作,首先activity必须实现view层的接口,然后在activity中必须创建preserent层的对象,为了调用preserent层实现类的具体方法;
public class VLayoutActivity extends AppCompatActivity implements IView {private RecyclerView recyclerView; private IVPresenter presenter; private BannerView bannerView; //存放各个模块的适配器 List mAdapter = new LinkedList<>(); @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_vlayout); recyclerView = (RecyclerView) findViewById(R.id.recyclerview); presenter = new IVPresenterImpl(this, this); initRecyclerView(); }private void initRecyclerView() { //获取DelegateAdapter DelegateAdapter delegateAdapter = presenter.initRecycler(recyclerView); //初始化轮播图 BaseAdapter bannerAdapter = presenter.initBanner(); mAdapter.add(bannerAdapter); //初始化九宫格 BaseAdapter gvMenuAdapter = presenter.initGvMenu(); mAdapter.add(gvMenuAdapter); //初始化跑马灯效果 BaseAdapter marqueeAdapter = presenter.initMarquee(); mAdapter.add(marqueeAdapter); //初始化标题 BaseAdapter titleAdapter = presenter.initTitle("豆瓣评分"); mAdapter.add(titleAdapter); //初始化listdelegateAdapter.setAdapters(mAdapter); }/** * 设置轮播图 */ @Override public void setBanner(BannerView bannerView, List pictures) { this.bannerView = bannerView; bannerView.setHintGravity(2); //设置位置 bannerView.setAnimationDuration(1000); //设置viewPager滑动动画持续时间 bannerView.setPlayDelay(2000); //设置轮播时间bannerView.setAdapter(new BannerAdapter(VLayoutActivity.this, pictures)); }/** * 九宫格点击事件 * * @param position */ @Override public void setClick(int position) { Toast.makeText(this, "点击了" + position, Toast.LENGTH_SHORT).show(); }/** * 初始化跑马灯效果 * * @param position */ @Override public void setMarqueeClick(int position) { Toast.makeText(this, "点击了" + position, Toast.LENGTH_SHORT).show(); }/** * 初始化标题 * * @param position */ @Override public void setTitleMoreClick(int position) { Toast.makeText(this, "点击了标题", Toast.LENGTH_SHORT).show(); }@Override protected void onPause() { super.onPause(); if (bannerView != null) { bannerView.pause(); } }@Override protected void onResume() { super.onResume(); if (bannerView != null) { bannerView.resume(); } } }

    推荐阅读