編輯:關於Android編程
好久沒寫博客了,今天沒事怒更一記。
如標題今天我們來模仿一下搜狐新聞,先上個效果圖.
1,接下來我們就來分析一下這個效果
下面的內容應該是用viewpager,頭部的選項卡我們用一個LinearLayout+HorizontalScrollView也可以實現,滾動效果的話我們可以用到我們學會的scrollTo,大致的思路理清,我們就開始碼代碼吧!
2,自定義LinearLayout
我們可以觀察到那個紅色的矩形應該是和整體的LinearLayout在一起,所以我們可以自定義LinearLayout畫出那個矩形,滾動就是改變畫矩形的位置即可
public class ViewpagerIndicator extends LinearLayout { /** * 畫筆,底部矩形 */ private Paint paint; /** * 子View個數 */ private int mCount; private int mTop; private int mWidth; private int mLeft; private int mHeight = 5; public OnTextClick onTextClick; public ViewpagerIndicator(Context context) { super(context); } public ViewpagerIndicator(Context context, AttributeSet attrs) { super(context, attrs); setBackgroundColor(Color.TRANSPARENT); paint = new Paint(); paint.setColor(getResources().getColor(R.color.red)); paint.setAntiAlias(true); } public interface OnTextClick{ public void textViewClick(int position); } public void setOnTextClick(OnTextClick onTextClick){ this.onTextClick = onTextClick; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //整體高度 mTop = getMeasuredHeight(); //整體寬度 int width = getMeasuredWidth(); //加上指示器高度 int height = mTop + mHeight; //指示器的寬度 mWidth = width / mCount; setMeasuredDimension(width, height); }
/** * 畫出指示器 * @param canvas */ protected void onDraw(Canvas canvas) { Rect rect = new Rect(mLeft, mTop, mLeft + mWidth, mTop + mHeight); canvas.drawRect(rect, paint); }
沒錯,就是倆句代碼,之後通過不斷的改變left就可以實現跟隨滾動的效果。
/** * 滾動效果 * @param position * @param positionOffset */ public void scrollTo(int position, float positionOffset) { mLeft = (int) ((position + positionOffset) * mWidth); postInvalidate(); }方法中的倆個參數我們可以通過viewpager的回調方法onPageScrolled中得到,position就是當前的選項卡,positionOffset相當於滑動的百分比0.0~0.0之間.
3,使用自定義控件
ok,大致的思路都已經理清,接下來我們就可以使用自己做的Indicator了。
先不要被眼前多如狗的TextView嚇到,其實都是粘貼復制上去的改了一個text就行,我們也可以在自己的LinearLayout中通過TextView t = new TextView();然後add進去,這倆種方法都可以。
但是我們顯然都不想給這麼多的textview都取id然後拿到它的實例再setOnClick,所以我們就可以在自定義的ViewGroup中直接set
@Override protected void onFinishInflate() { super.onFinishInflate(); mCount = getChildCount(); /** * 監聽點擊事件,回調接口 */ for (int i = 0 ;i通過回調接口我們就輕易的拿到了所點擊的是哪一頁選項卡,接下來我們來看看使用方法
public class MainActivity extends Activity implements ViewPager.OnPageChangeListener,ViewpagerIndicator.OnTextClick{ private ViewPager viewPager; private int lastX = 0; private ViewpagerIndicator indicator; private HorizontalScrollView horizontalScrollView; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initViews(); } private void initViews() { viewPager = (ViewPager) findViewById(R.id.viewpager); indicator = (ViewpagerIndicator) findViewById(R.id.indicator); indicator.setOnTextClick(this); horizontalScrollView = (HorizontalScrollView) findViewById(R.id.horizon); viewPager.setAdapter(new MyAdapter()); viewPager.setOnPageChangeListener(this); }一些必要的實例化.
/** * 只有當從第一項滾動第二項或者從第二項滾動第一項時,整體不動指示器單獨滾動,其余都是整個布局滾動 * @param position * @param positionOffset * @param positionOffsetPixels */ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { if (!(position == 0 && positionOffset - lastX >= 0) || !(position == 1 && positionOffset - lastX <= 0)){ horizontalScrollView.scrollTo((int)((positionOffset+position-1)*indicator.getIndicatorWidth()), 0); } indicator.scrollTo(position, positionOffset); lastX = (int) positionOffset; } @Override public void onPageSelected(int position) { indicator.resetTextViewColor(); indicator.setFocusTextView(position); } @Override public void onPageScrollStateChanged(int state) { }通過觀察搜狐新聞我們可以看到,當從第一頁滑動到第二頁時,只有Indicator滾動了,之後都是整體滾動,所以我們要做好判斷,整體滾動的時候indicator就相當於停留在了顯示出來的第二個選項卡,接下來我們看看實際效果.
效果還是闊以的嘛,咔咔。
項目源碼
前言——項目中需要用到對用戶頭像的裁剪和上傳功能。關於裁剪,一開始是想自己來做,但是覺得這個東西應該谷歌有開發吧,於是一搜索官方文檔,果然有。於是,就果斷無恥地用了And
在安卓開發中,谷歌已經為我們提供了許多原生控件,基本上能夠滿足我們日常的開發需求,但是某些項目中原生控件可能達不到產品所要求的各式各樣的酷炫效果或功能效果,這個時候我們只
前不久換了台macbook,然後自己就把開發環境給配好了,本來這事就這麼過去了,今天有位博友留言讓我寫一篇關於配置的文章,考慮到這個東西確實以後可能還會用,那就寫下來,分
我們知道apk生成後所有的java生成的class文件都被dx命令整合成了一個classes.dex文件,當apk運行時dalvik虛擬機加載classes.