zl程序教程

您现在的位置是:首页 >  其它

当前栏目

仿今日头条顶部导航效果

效果 导航 头条 今日 顶部
2023-09-14 08:58:19 时间
 之前发现很多人在群里面、论坛上求网易新闻客户端的源码,之后我就去下了个网易新闻客户端和今日头条新闻客户端,发现他们的大体是一样的,于是在最近的空闲时间,便去琢磨如何去实现这样一个APP。 p span >要知道它们是如何实现的,用到了什么第三方库文件,反编译便是很好的一个了解方法,如果你想要了解如何反编译可以点击这个链接:反编译就这么简单

只是一般的APK打包后都是被混淆过的,所以没那么好了解他的每个界面是如何实现的,没事,那就自己慢慢摸索或则从它的资源文件中提取布局了解下整体的大概情况。

我通过反编译 --今日头条:

知道了它用到的架包有,提取了有用的部分:

1.android-support-v4.jar (最常用的官方架包之一)

2.android-support-v7.jar (主要用于ActionBar的低版本兼容)

3.handmark.pulltorefresh.library  (图片的下拉刷新包)

4.slidingmenu.lib  (侧拉菜单包)   使用方法配置以及下载:点击这里

5.umeng (友盟的官方架包)

自己要在加用上的架包有:

1.Android-Universal-Image-Loader  (图片的异步加载包)   使用方法配置以及下载:点击这里

注:发现架包中有aaa什么的命名,说明它被混淆过,所以要想进一步获取它的源码很困难,只能按照自己的思路去走。


好的,大体了解了它的整体结构,下面就开始它是如何开发的把:

注:本代码内用到的资源文件和属性配置部分从APK反编译的资源(SRC文件)中提取,为了达到更好的实现效果。

一.首先构建大体的框架,架包等用到的时候在导入

命名规范可以参考:android命名规范

二.进行配置

首先去掉应用的title栏目:

采取修改AndroidManifest.xml文件中application的android:theme="@style/AppTheme"属性:


view.startAnimation(start_anima);   start_anima.setAnimationListener(new AnimationListener() {              @Override       public void onAnimationStart(Animation animation) {           // TODO Auto-generated method stub                  }              @Override       public void onAnimationRepeat(Animation animation) {           // TODO Auto-generated method stub                  }              @Override       public void onAnimationEnd(Animation animation) {           // TODO Auto-generated method stub           redirectTo();//跳转       }   });  
LinearLayout 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"       android:orientation="vertical"          include layout="@layout/main_head" /         LinearLayout           android:layout_width="match_parent"           android:layout_height="40.0dip"           android:background="#fff3f3f3"           android:orientation="horizontal"              RelativeLayout               android:id="@+id/rl_column"               android:layout_width="match_parent"               android:layout_height="40.0dip"               android:layout_weight="1.0"                  com.topnews.view.ColumnHorizontalScrollView                   android:id="@+id/mColumnHorizontalScrollView"                   android:layout_width="match_parent"                   android:layout_height="40.0dip"                   android:scrollbars="none"                      LinearLayout                       android:id="@+id/mRadioGroup_content"                       android:layout_width="fill_parent"                       android:layout_height="40.0dip"                       android:layout_centerVertical="true"                       android:gravity="center_vertical"                       android:orientation="horizontal"                       android:paddingLeft="10.0dip"                       android:paddingRight="10.0dip" /                 /com.topnews.view.ColumnHorizontalScrollView                 ImageView                   android:id="@+id/shade_left"                   android:layout_width="10.0dip"                   android:layout_height="40.0dip"                   android:layout_alignParentLeft="true"                   android:layout_centerVertical="true"                   android:background="@drawable/channel_leftblock"                   android:visibility="gone" /                 ImageView                   android:id="@+id/shade_right"                   android:layout_width="10.0dip"                   android:layout_height="40.0dip"                   android:layout_alignParentRight="true"                   android:layout_centerVertical="true"                   android:background="@drawable/channel_rightblock"                   android:visibility="visible" /             /RelativeLayout             LinearLayout               android:id="@+id/ll_more_columns"               android:layout_width="wrap_content"               android:layout_height="40.0dip"                  ImageView                   android:id="@+id/button_more_columns"                   android:layout_width="40.0dip"                   android:layout_height="40.0dip"                   android:layout_gravity="center_vertical"                   android:src="@drawable/channel_glide_day_bg" /             /LinearLayout         /LinearLayout         View           android:id="@+id/category_line"           android:layout_width="fill_parent"           android:layout_height="0.5dip"           android:background="#ffdddddd" /         android.support.v4.view.ViewPager           android:id="@+id/mViewPager"           android:layout_width="match_parent"           android:layout_height="match_parent" /    /LinearLayout   
由于发现HorizontalScrollView左右拖动的时候没有那种阴影效果,所以在这里,我们发现了头条的资源文件下有这么2个文件:


这个就是它在白天模式和黑夜模式下用的阴影图片。那我们可以采取重写HorizontalScrollView来判断滚动,如果滚动时候不是在最左边,显示左边阴影,不是在最右边,显示右边阴影。


public class ColumnHorizontalScrollView extends HorizontalScrollView {       /** 传入整体布局  */       private View ll_content;       /** 传入更多栏目选择布局 */       private View ll_more;       /** 传入拖动栏布局 */       private View rl_column;       /** 左阴影图片 */       private ImageView leftImage;       /** 右阴影图片 */       private ImageView rightImage;       /** 屏幕宽度 */       private int mScreenWitdh = 0;       /** 父类的活动activity */       private Activity activity;              public ColumnHorizontalScrollView(Context context) {           super(context);       }       public ColumnHorizontalScrollView(Context context, AttributeSet attrs) {           super(context, attrs);       }       public ColumnHorizontalScrollView(Context context, AttributeSet attrs,               int defStyle) {           super(context, attrs, defStyle);       }       /**        * 在拖动的时候执行       * */       @Override       protected void onScrollChanged(int paramInt1, int paramInt2, int paramInt3, int paramInt4) {           // TODO Auto-generated method stub           super.onScrollChanged(paramInt1, paramInt2, paramInt3, paramInt4);           shade_ShowOrHide();           if(!activity.isFinishing()   ll_content !=null   leftImage!=null   rightImage!=null   ll_more!=null   rl_column !=null){               if(ll_content.getWidth()  = mScreenWitdh){                   leftImage.setVisibility(View.GONE);                   rightImage.setVisibility(View.GONE);               }           }else{               return;           }           if(paramInt1 ==0){               leftImage.setVisibility(View.GONE);               rightImage.setVisibility(View.VISIBLE);               return;           }           if(ll_content.getWidth() - paramInt1 + ll_more.getWidth() + rl_column.getLeft() == mScreenWitdh){               leftImage.setVisibility(View.VISIBLE);               rightImage.setVisibility(View.GONE);               return;           }           leftImage.setVisibility(View.VISIBLE);           span      /span rightImage.setVisibility(View.VISIBLE);       }       /**        * 传入父类布局中的资源文件       * */       public void setParam(Activity activity, int mScreenWitdh,View paramView1,ImageView paramView2, ImageView paramView3 ,View paramView4,View paramView5){           this.activity = activity;           this.mScreenWitdh = mScreenWitdh;           ll_content = paramView1;           leftImage = paramView2;           rightImage = paramView3;           ll_more = paramView4;           rl_column = paramView5;       }       /**        * 判断左右阴影的显示隐藏效果       * */       public void shade_ShowOrHide() {           if (!activity.isFinishing()   ll_content != null) {               measure(0, 0);               //如果整体宽度小于屏幕宽度的话,那左右阴影都隐藏               if (mScreenWitdh  = getMeasuredWidth()) {                   leftImage.setVisibility(View.GONE);                   rightImage.setVisibility(View.GONE);               }           } else {               return;           }           //如果滑动在最左边时候,左边阴影隐藏,右边显示           if (getLeft() == 0) {               leftImage.setVisibility(View.GONE);               rightImage.setVisibility(View.VISIBLE);               return;           }           //如果滑动在最右边时候,左边阴影显示,右边隐藏           if (getRight() == getMeasuredWidth() - mScreenWitdh) {               leftImage.setVisibility(View.VISIBLE);               rightImage.setVisibility(View.GONE);               return;           }           //否则,说明在中间位置,左、右阴影都显示           leftImage.setVisibility(View.VISIBLE);           rightImage.setVisibility(View.VISIBLE);       }  

之后

private ArrayList NewsClassify newsClassify=new ArrayList NewsClassify

根据newsClassify这个栏目分类列表里面的数量进行添加栏目。(这里首先采用了自己限定的ITEM,而没有进行数据库的操作,以后加上)

ViewPage的适配器NewsFragmentPagerAdapter,通过ViewPage切换对应栏目的的Fragment:


public class NewsFragmentPagerAdapter extends FragmentPagerAdapter {       private ArrayList Fragment  fragments;       private FragmentManager fm;       public NewsFragmentPagerAdapter(FragmentManager fm) {           super(fm);           this.fm = fm;       }       public NewsFragmentPagerAdapter(FragmentManager fm,               ArrayList Fragment  fragments) {           super(fm);           this.fm = fm;           this.fragments = fragments;       }       @Override       public int getCount() {           return fragments.size();       }       @Override       public Fragment getItem(int position) {           return fragments.get(position);       }       @Override       public int getItemPosition(Object object) {           return POSITION_NONE;       }       public void setFragments(ArrayList Fragment  fragments) {           if (this.fragments != null) {               FragmentTransaction ft = fm.beginTransaction();               for (Fragment f : this.fragments) {                   ft.remove(f);               }               ft.commit();               ft = null;               fm.executePendingTransactions();           }           this.fragments = fragments;           notifyDataSetChanged();       }       @Override       public Object instantiateItem(ViewGroup container, final int position) {           Object obj = super.instantiateItem(container, position);           return obj;       }  
    for(int i = 0; i  count; i++){           LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(mItemWidth , LayoutParams.WRAP_CONTENT);           params.leftMargin = 10;           params.rightMargin = 10;           TextView localTextView = new TextView(this);           localTextView.setTextAppearance(this, R.style.top_category_scroll_view_item_text);           localTextView.setBackgroundResource(R.drawable.radio_buttong_bg);           localTextView.setGravity(Gravity.CENTER);           localTextView.setPadding(5, 0, 5, 0);           localTextView.setId(i);           localTextView.setText(newsClassify.get(i).getTitle());           localTextView.setTextColor(getResources().getColorStateList(R.color.top_category_scroll_text_color_day));           if(columnSelectIndex == i){               localTextView.setSelected(true);           }           localTextView.setOnClickListener(new OnClickListener() {                          @Override               public void onClick(View v) {                     for(int i = 0;i   mRadioGroup_content.getChildCount();i++){                         View localView = mRadioGroup_content.getChildAt(i);                         if (localView != v)                             localView.setSelected(false);                         else{                             localView.setSelected(true);                             mViewPager.setCurrentItem(i);                         }                     }                     Toast.makeText(getApplicationContext(), newsClassify.get(v.getId()).getTitle(), Toast.LENGTH_SHORT).show();               }           });           mRadioGroup_content.addView(localTextView, i ,params);       }  
    private void selectTab(int tab_postion) {           columnSelectIndex = tab_postion;           for (int i = 0; i   mRadioGroup_content.getChildCount(); i++) {               View checkView = mRadioGroup_content.getChildAt(tab_postion);               int k = checkView.getMeasuredWidth();               int l = checkView.getLeft();               int i2 = l + k / 2 - mScreenWidth / 2;               // rg_nav_content.getParent()).smoothScrollTo(i2, 0);               mColumnHorizontalScrollView.smoothScrollTo(i2, 0);               // mColumnHorizontalScrollView.smoothScrollTo((position - 2) *               // mItemWidth , 0);           }           //判断是否选中           for (int j = 0; j    mRadioGroup_content.getChildCount(); j++) {               View checkView = mRadioGroup_content.getChildAt(j);               boolean ischeck;               if (j == tab_postion) {                   ischeck = true;               } else {                   ischeck = false;               }               checkView.setSelected(ischeck);           }       }  
玩不转的企业微信侧边栏 如果你不知道 企业微信侧边栏 是什么,那就可以划走这篇文章了。如果你知道这是个啥,那你一定非常苦恼要怎么开始。 从去年就开始就一直有在做企业微信侧边栏的应用。说实话,开发和调试体验实在是太糟糕了,而且上手的时候跟本连怎么打开它都不知道。
聊聊大麦网UWP版的首页顶部图片联动效果的实现方法 原文:聊聊大麦网UWP版的首页顶部图片联动效果的实现方法 随着Windows10的发布,国内已经有越来越多的厂商上架了自家的通用应用程序客户端,比如QQ、微博、大麦等。所实话,他们设计的确实很好,很符合Windows10 的设计风格和产品理念,而对于开发者而言,当我们发现一个不错的UI设计风格不禁想自己动手也写一个类似的效果玩玩。