1. 程式人生 > >Android開發ViewPager和Fragment結合使用實現新聞類app( 三 )(基本成型的app)

Android開發ViewPager和Fragment結合使用實現新聞類app( 三 )(基本成型的app)

//該類為我們的標題欄的自定義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);
    }
}