Android開發ViewPager和Fragment結合使用實現新聞類app( 三 )(基本成型的app)
阿新 • • 發佈:2019-01-03
//該類為我們的標題欄的自定義View public class MyLinearLayout extends LinearLayout { public MyLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } private void init(Context context, AttributeSet attrs) { //自定義屬性: TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.MyLinearLayout); title_visible_count = array.getInteger(R.styleable.MyLinearLayout_linear_my_view_count, 0); //獲取螢幕的寬和高 screenInfo = new GetScreenInfo(context); getHeight = screenInfo.getScreenHeight(); getWidth = screenInfo.getScreenWidth(); initPaintAndLine(); array.recycle(); } private GetScreenInfo screenInfo; private float layoutWidth, layoutHeight; public static int title_visible_count; @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); /* 重寫onMeasure()方法是為了能適配不同大小的機型,如果我們不重寫該方法,在4.0英寸的手機上和5.5英 寸的手機上都使用同一個height,那給使用者的感覺肯定是不舒服的,所以我們能通過該方法實現一點簡單的適配 功能,當然如果你剛開始學習自定義View,那你可以不用重寫該方法,直接在xml中的height值寫成固定值就可以了。 */ Log.d("zt", "onmeasure"); int getWidthpx, widthMode, getHeightpx, heightMode; getWidthpx = MeasureSpec.getSize(widthMeasureSpec); widthMode = MeasureSpec.getMode(widthMeasureSpec); getHeightpx = MeasureSpec.getSize(heightMeasureSpec); heightMode = MeasureSpec.getMode(heightMeasureSpec); /* 該出Mode一共有3中,EXACTLY,AT_MOST,UNSPECIFIED;其中當我們在xml中設定了width或者height為match_parent或者某個 固定值時,那麼這個Mode就是EXACTLY,如果設定成wrap_content的話,那麼這個Mode就是AT_MOST, UNSPECIFIED是什麼我也不太清楚, 如果你用過這個值,可以告訴留言告訴我啊!哈哈!*/ if (widthMode == MeasureSpec.EXACTLY) { //當xml中width被設定成了固定的值或者設定成match_parent那麼我們就直接用這個值 layoutWidth = getWidthpx; } else { //否則我們就使用getScreenSize()方法中獲得的螢幕的寬度。 layoutWidth = getWidth; } if (heightMode == MeasureSpec.EXACTLY) { layoutHeight = getHeightpx; } else { //如果xml中沒有定義高度,那麼我們就讓標題欄佔螢幕的1/14,這樣大概差不多比較合適,當然,你可以自己改變這個值。 layoutHeight = getHeight / 15; } setMeasuredDimension((int) layoutWidth, (int) layoutHeight); } private float getHeight, getWidth; public Map<TextView,Integer> a=new HashMap<TextView,Integer>(); private int textViewPosition; private TextView getTextView(String name) { //因為在新聞的標題欄裡,有很多很多標題,可能多達20個,我們不可能在佈局檔案裡一直新增吧,所以就直接動態生成TextView. TextView tv = new TextView(getContext()); Log.d("zt", "getTextView"); a.put(tv,textViewPosition++); LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); //根據自定義屬性中的控制顯示title數量的值,來動態改變width的值,使得顯示的數量和定義的相符合。 lp.width = (int) (getWidth / title_visible_count); lp.gravity = Gravity.CENTER; tv.setText(name + ""); tv.setGravity(Gravity.CENTER); tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15); tv.setTextColor(Color.GRAY); tv.setLayoutParams(lp); return tv; } private int count; //該自定義View中暴露出來的方法,讓外界呼叫 public void createTextView(ArrayList list) { if (list != null && list.size() > 0) { this.removeAllViews(); count = list.size(); for (int i = 0; i < list.size(); i++) { MyLinearLayout.this.addView(getTextView(list.get(i) + "")); } } } //10.2 private Paint paint; private float mLineWidth; private float lineEndX; private float lineStartX; private int currentPositon; private void initPaintAndLine() { paint = new Paint(); paint.setStrokeWidth(4); paint.setColor(Color.RED); paint.setStyle(Paint.Style.STROKE); paint.setAntiAlias(true); // mLineWidth= (getWidth/title_visible_count*2/3); mLineWidth = getWidth / (title_visible_count * 2); lineEndX = (int) (mLineWidth + mLineWidth); lineStartX = (getWidth / title_visible_count - mLineWidth) / 2.0f; } private MyLinearChangedListener myLinearChangeListener; public void setOnMyLiChangListener(MyLinearChangedListener my) { myLinearChangeListener = my; } //回撥介面 public interface MyLinearChangedListener { void onMyLiChed(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawLine(lineStartX, getMeasuredHeight(), lineEndX, getMeasuredHeight(), paint); Log.d("zt", "onDraw"); } private float titleWidth; //暴露該方法讓外界呼叫,來動態改變標題底部的紅色的線,以及標題的顏色 public void lineScroll(int position, float offset) { titleWidth = getWidth / title_visible_count; if ((offset * getWidth) < (getWidth / 2)) { lineEndX = mLineWidth + titleWidth * offset * 2.0f + titleWidth * position + titleWidth * 1.0f / 4.0f; } else { lineStartX = lineEndX - (1.0f - offset) * 2.0f * titleWidth - mLineWidth; } Log.d("hehe", lineEndX - lineStartX + ""); invalidate(); linearScroll(position, offset); } private void linearScroll(int position,float offset){ currentPositon=position; float titleWidth=getWidth/title_visible_count; if(position>=(title_visible_count/2)&&offset>0&&getChildCount()>title_visible_count&&position<=5){ this.scrollTo((int) ((position-(title_visible_count-4))*titleWidth+(titleWidth*offset)),0); } } public void setTitleBackGround(int position) { for(int i=0;i<getChildCount();i++){ TextView tv= (TextView) getChildAt(i); tv.setTextColor(Color.GRAY); } TextView view= (TextView) getChildAt(position); view.setTextColor(Color.RED); } }