Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 使用ViewPager實現問卷答題效果

使用ViewPager實現問卷答題效果

編輯:關於Android編程

總覺得應該在每一個項目中汲取一點溫存。。。哪怕是只有一點點。。。
先看實現的效果圖,就是使用Viewpager控件進行左右翻頁,然後設置邊距為負數,進行上一頁和下一頁的部分顯示(設置透明度進行區分),做一個引導的效果,而且重寫了Viewpager,主要是為了實現未選定這一頁的答案,禁止下一頁的滑動。假設你點擊了最後一頁的答案後自動跳轉到結果頁面,按照自己設計的權重進行分數顯示。這裡自定義一個類似進度條的指針顯示,是繼承了View通過畫布繪制出來的效果。

這裡寫圖片描述

這裡寫圖片描述

這裡寫圖片描述

首先我自己對於數據庫的理解就是在SQLite Expert Professional 3中編輯新建數據庫,然後把那個db文件放到assert資源文件夾中進行訪問,因為裡面都是一些基礎數據。就到網上找了,發現這的是有這麼神奇的東西,看來是做後台數據人員習慣了數據庫設計的方式,都想這麼做。。。我就是這麼想的

act_oldtesting.xml




    

    

        

        

        

        

            

            

            
        
    

1、題目中的數據來源:自己進行數據庫的設計編輯(SQLite Expert Professional 3)建議使用專業版,不要用個人版,然後采用AssetsDatabaseManager類獲取assert資源文件目錄下的對應db文件。

AssetsDatabaseManager.java

package com.example.db;

import java.io.File;  
import java.io.FileOutputStream;  
import java.io.InputStream;  
import java.io.OutputStream;  
import java.util.HashMap;  
import java.util.Map;  

import android.content.Context;  
import android.content.SharedPreferences;  
import android.content.res.AssetManager;  
import android.database.sqlite.SQLiteDatabase;  
import android.util.Log;  

/** 
 * This is a Assets Database Manager 
 * Use it, you can use a assets database file in you application 
 * It will copy the database file to "/data/data/[your application package name]/database" when you first time you use it 
 * Then you can get a SQLiteDatabase object by the assets database file  
 * @author ZSJ 
 * @time 2016-07-11 
 *  
 *  
 * How to use: 
 * 1. Initialize AssetsDatabaseManager 
 * 2. Get AssetsDatabaseManager 
 * 3. Get a SQLiteDatabase object through database file 
 * 4. Use this database object 
 *  
 * Using example: 
 * AssetsDatabaseManager.initManager(getApplication()); // this method is only need call one time 
 * AssetsDatabaseManager mg = AssetsDatabaseManager.getManager();   // get a AssetsDatabaseManager object 
 * SQLiteDatabase db1 = mg.getDatabase("db1.db");   // get SQLiteDatabase object, db1.db is a file in assets folder 
 * db1.???  // every operate by you want 
 * Of cause, you can use AssetsDatabaseManager.getManager().getDatabase("xx") to get a database when you need use a database 
 */  
public class AssetsDatabaseManager {  
    private static String tag = "AssetsDatabase"; // for LogCat  
    private static String databasepath = "/data/data/%s/databases"; // %s is packageName  


    // A mapping from assets database file to SQLiteDatabase object  
    private Map databases = new HashMap();  

    // Context of application  
    private Context context = null;

    // Singleton Pattern  
    private static AssetsDatabaseManager mInstance = null;

    /** 
     * Initialize AssetsDatabaseManager 
     * @param context, context of application 
     */  
    public static void initManager(Context context){  
        if(mInstance == null){  
            mInstance = new AssetsDatabaseManager(context);  
        }  
    }  

    /** 
     * Get a AssetsDatabaseManager object 
     * @return, if success return a AssetsDatabaseManager object, else return null 
     */  
    public static AssetsDatabaseManager getManager(){  
        return mInstance;  
    }  

    private AssetsDatabaseManager(Context context){  
        this.context = context;  
    }  

    /** 
     * Get a assets database, if this database is opened this method is only return a copy of the opened database 
     * @param dbfile, the assets file which will be opened for a database 
     * @return, if success it return a SQLiteDatabase object else return null 
     */  
    public SQLiteDatabase getDatabase(String dbfile) {  
        if(databases.get(dbfile) != null){  
            Log.i(tag, String.format("Return a database copy of %s", dbfile));  
            return (SQLiteDatabase) databases.get(dbfile);  
        }  
        if(context==null)  
            return null;  

        Log.i(tag, String.format("Create database %s", dbfile));  
        String spath = getDatabaseFilepath();  
        String sfile = getDatabaseFile(dbfile);  

        File file = new File(sfile);  
        SharedPreferences dbs = context.getSharedPreferences(AssetsDatabaseManager.class.toString(), 0);  
        boolean flag = dbs.getBoolean(dbfile, false); // Get Database file flag, if true means this database file was copied and valid  
        if(!flag || !file.exists()){  
            file = new File(spath);  
            if(!file.exists() && !file.mkdirs()){  
                Log.i(tag, "Create \""+spath+"\" fail!");  
                return null;  
            }  
            if(!copyAssetsToFilesystem(dbfile, sfile)){  
                Log.i(tag, String.format("Copy %s to %s fail!", dbfile, sfile));  
                return null;  
            }  

            dbs.edit().putBoolean(dbfile, true).commit();  
        }  

        SQLiteDatabase db = SQLiteDatabase.openDatabase(sfile, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);  
        if(db != null){  
            databases.put(dbfile, db);  
        }  
        return db;  
    }  

    private String getDatabaseFilepath(){  
        return String.format(databasepath, context.getApplicationInfo().packageName);  
    }  

    private String getDatabaseFile(String dbfile){  
        return getDatabaseFilepath()+"/"+dbfile;  
    }  

    private boolean copyAssetsToFilesystem(String assetsSrc, String des){  
        Log.i(tag, "Copy "+assetsSrc+" to "+des);  
        InputStream istream = null;  
        OutputStream ostream = null;  
        try{  
            AssetManager am = context.getAssets();  
            istream = am.open(assetsSrc);  
            ostream = new FileOutputStream(des);  
            byte[] buffer = new byte[1024];  
            int length;  
            while ((length = istream.read(buffer))>0){  
                ostream.write(buffer, 0, length);  
            }  
            istream.close();  
            ostream.close();  
        }  
        catch(Exception e){  
            e.printStackTrace();  
            try{  
                if(istream!=null)  
                    istream.close();  
                if(ostream!=null)  
                    ostream.close();  
            }  
            catch(Exception ee){  
                ee.printStackTrace();  
            }  
            return false;  
        }  
        return true;  
    }  

    /** 
     * Close assets database 
     * @param dbfile, the assets file which will be closed soon 
     * @return, the status of this operating 
     */  
    public boolean closeDatabase(String dbfile){  
        if(databases.get(dbfile) != null){  
            SQLiteDatabase db = (SQLiteDatabase) databases.get(dbfile);  
            db.close();  
            databases.remove(dbfile);  
            return true;  
        }  
        return false;  
    }  

    /** 
     * Close all assets database 
     */  
    static public void closeAllDatabase(){  
        Log.i(tag, "closeAllDatabase");  
        if(mInstance != null){  
            for(int i=0; i

大概就是到assert中讀取db文件,獲取到那個db對象,然後封裝DBManager這個工具類
DBManager.java

package com.example.db;
import android.app.Application;
import android.database.sqlite.SQLiteDatabase;

public class DBManager {

    public static SQLiteDatabase getdb(Application mApplication) {
        // 初始化,只需要調用一次
        AssetsDatabaseManager.initManager(mApplication);
        // 獲取管理對象,因為數據庫需要通過管理對象才能夠獲取
        AssetsDatabaseManager mg = AssetsDatabaseManager.getManager();
        // 通過管理對象獲取數據庫
        SQLiteDatabase db = mg.getDatabase("test_questions.db");
        return db;
    }

}

2、主要的核心代碼Activity文件

MyOldtestAct.java中的代碼

package com.example.viewpagerdemo;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioButton;

import com.example.adapter.VPAdapter;
import com.example.db.DBManager;
import com.example.model.Questions;
import com.example.view.MyViewPager;

public class MyOldtestAct extends Activity implements OnClickListener {
    private ImageView btnBack;
    private MyViewPager viewPager;
    // 存放子項view
    private List viewItems = new ArrayList();
    // adapter
    private VPAdapter viewpagerAdpter;
    // 定義問題的集合
    List questionsList;
    private List questionList;
    private LinearLayout mViewpagef;
    private LinearLayout vpLinparentnow; // 當前的viewpager嵌套在外層的linerlayout
    private LinearLayout vpLinparentnext; // 下一個的viewpager嵌套在外層的linerlayout
    private LinearLayout vpLinparenttop; // 上一個的viewpager嵌套在外層的linerlayout

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.act_oldtest);
        setView();
        initData();
    }

    protected void setView() {
        mViewpagef = (LinearLayout) findViewById(R.id.vpfather);
        btnBack = (ImageView) findViewById(R.id.btn_back);
        viewPager = (MyViewPager) findViewById(R.id.vote_submit_viewpager);
        btnBack.setOnClickListener(this);
        for (int i = 0; i < 10; i++) {
            viewItems.add(getLayoutInflater().inflate(R.layout.act_oldtesting,
                    null));
        }
        // 第一次進入的時候不執行該方法,設置透明度
        vpLinparentnext = (LinearLayout) viewItems.get(1).findViewById(
                R.id.vp_parent);
        vpLinparentnext.setAlpha(0.5f);// 初始化的時候默認把第二頁透明度設置為0.5
    }

    protected void initData() {
        // 獲取數據庫
        SQLiteDatabase db = DBManager.getdb(getApplication());
        questionsList = new ArrayList();
        questionList = new ArrayList();
        // 把數據庫的數據查詢出來
        Cursor cursor = db.query("test_bank", null, null, null, null, null,
                null);
        while (cursor.moveToNext()) {
            String questionId = cursor.getString(0);
            String test_cotent = cursor.getString(1);
            Questions Q = new Questions(questionId, test_cotent);
            questionsList.add(Q);
        }
        // 在1-5產生一個隨機數,sqlite中有5組題庫
        Random rand = new Random();
        int randNum = rand.nextInt(5) + 1;
        Log.w("randNum", String.valueOf(randNum));
        // 根據產生的隨機數獲取題目
        switch (randNum) {
        case 1:
            for (int i = 1; i <= 10; i++) {
                questionList.add(i + "、"
                        + questionsList.get(i - 1).getTest_cotent());
            }
            break;
        case 2:
            for (int i = 1; i <= 10; i++) {
                questionList.add(i + "、"
                        + questionsList.get(i + 9).getTest_cotent());
            }
            break;
        case 3:
            for (int i = 1; i <= 10; i++) {
                questionList.add(i + "、"
                        + questionsList.get(i + 19).getTest_cotent());
            }
            break;
        case 4:
            for (int i = 1; i <= 10; i++) {
                questionList.add(i + "、"
                        + questionsList.get(i + 29).getTest_cotent());
            }
            break;
        case 5:
            for (int i = 1; i <= 10; i++) {
                questionList.add(i + "、"
                        + questionsList.get(i + 39).getTest_cotent());
            }
            break;
        }
        viewpagerAdpter = new VPAdapter(this, viewItems, questionList);
        viewPager.setOffscreenPageLimit(3);// viewPager設置緩存的頁面數
        viewPager.setPageMargin(-20);// 設置2張圖之前的間距,-20就是會有邊距的效果
        MyOnPageChangeListener myOnPageChangeListener = new MyOnPageChangeListener();
        viewPager.setOnPageChangeListener(myOnPageChangeListener);
        viewPager.setAdapter(viewpagerAdpter);
    }

    public class MyOnPageChangeListener implements OnPageChangeListener {
        @Override
        public void onPageSelected(int position) {
            vpLinparentnow = (LinearLayout) viewItems.get(position)
                    .findViewById(R.id.vp_parent);
            vpLinparentnow.setAlpha(1f); // 設置當前的alpha為1
            if (position == 0) {
                vpLinparentnext = (LinearLayout) viewItems.get(position + 1)
                        .findViewById(R.id.vp_parent);
                vpLinparentnext.setAlpha(0.5f);
            } else if (position == viewItems.size() - 1) {
                vpLinparenttop = (LinearLayout) viewItems.get(position - 1)
                        .findViewById(R.id.vp_parent);
                vpLinparenttop.setAlpha(0.5f);
            } else {
                vpLinparentnext = (LinearLayout) viewItems.get(position + 1)
                        .findViewById(R.id.vp_parent);
                vpLinparenttop = (LinearLayout) viewItems.get(position - 1)
                        .findViewById(R.id.vp_parent);
                vpLinparentnext.setAlpha(0.5f);
                vpLinparenttop.setAlpha(0.5f);
            }
            // 判斷當前的選項是否有選中的
            RadioButton chkNothave = (RadioButton) viewItems.get(position)
                    .findViewById(R.id.chk_nothave);
            RadioButton chkSometimes = (RadioButton) viewItems.get(position)
                    .findViewById(R.id.chk_sometimes);
            RadioButton chkUsual = (RadioButton) viewItems.get(position)
                    .findViewById(R.id.chk_usual);
            // 如果當前有選中的項,則可以滑動
            if (chkNothave.isChecked() || chkSometimes.isChecked()
                    || chkUsual.isChecked()) {
                viewPager.isCompleteable(true);
            } else {
                viewPager.isCompleteable(false);
            }
        }

        // 做刷新操作,不然View會重疊有重影
        @Override
        public void onPageScrolled(int position, float positionOffset,
                int positionOffsetPixels) {
            // to refresh frameLayout
            if (mViewpagef != null) {
                mViewpagef.invalidate();
            }
        }

        @Override
        public void onPageScrollStateChanged(int arg0) {

        }
    }

    /**
     * @param index
     *  根據索引值切換頁面
     */
    public void setCurrentView(int index) {
        viewPager.setCurrentItem(index);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.btn_back:
            finish();
            break;
        }
    }

}

3、MyViewpager自定義的Viewpager,傳入Boolean進行上下滑頁的控制。(細節)

package com.example.view;

import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;

/**
 * @author zsj 重寫ViewPager禁止其左右滑動
 */
public class MyViewPager extends ViewPager {

    private float x;
    private float mLastMotionX;
    private boolean isComplete = false;

    public void isCompleteable(boolean iscomplete) {
        this.isComplete = iscomplete;
    }

    public MyViewPager(Context context) {
        super(context);
    }

    public MyViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onTouchEvent(MotionEvent arg0) {
        return super.onTouchEvent(arg0);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            x = ev.getX(); // 在手指按下的時獲取X軸的坐標
            break;
        case MotionEvent.ACTION_MOVE:
            mLastMotionX = ev.getX() - x; // 滑動的距離
            if (!isComplete) {
                if (mLastMotionX < 0) {
                    return false;  //不可以滑動
                }
            }
            break;
        }
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent arg0) {
        return super.onInterceptTouchEvent(arg0);
    }

}

4、對了,還有自定義的PagerAdapter

VPAdapter.java

package com.example.adapter;

import java.util.List;

import com.example.viewpagerdemo.MyOldtestAct;
import com.example.viewpagerdemo.R;
import com.example.viewpagerdemo.TestresultAct;

import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;

public class VPAdapter extends PagerAdapter {
    // 傳遞過來的頁面view的集合
    private List viewItems;
    // 每個item的頁面view
    private View convertView;
    private MyOldtestAct mContext = null;
    private List dataItems;
    ViewHolder holder = null;
    int[] mycount = new int[10];

    // 構造方法
    public VPAdapter(MyOldtestAct context, List viewItems,
            List dataItems) {
        this.mContext = context;
        this.viewItems = viewItems;
        this.dataItems = dataItems;
    }

    // 獲取總數
    @Override
    public int getCount() {
        return viewItems.size();
    }

    // 官方推薦這麼寫
    @Override
    public boolean isViewFromObject(View arg0, Object arg1) {
        return arg0 == arg1;
    }

    // 移除頁卡
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView(viewItems.get(position));
    }

    // 這裡返回View
    @Override
    public Object instantiateItem(ViewGroup container, final int position) {
        // 初始化viewholder
        holder = new ViewHolder();
        // 取到每一個子項,進行賦值
        convertView = viewItems.get(position);
        holder.rapQuestion = (RadioGroup) convertView
                .findViewById(R.id.rap_question);
        holder.questionContent = (TextView) convertView
                .findViewById(R.id.questioncontent);
        holder.txtTitle = (TextView) convertView.findViewById(R.id.txt_title);
        holder.questionContent.setText(dataItems.get(position));
        holder.txtTitle.setText(position + 1 + "/10");
        // 監聽RadioGrop的選中事件
        holder.rapQuestion
                .setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
                    @Override
                    public void onCheckedChanged(RadioGroup group, int checkedId) {
                        if (position != viewItems.size() - 1) {
                            mContext.setCurrentView(position + 1);
                        }// 點擊默認跳轉到下一頁
                        switch (checkedId) {
                        case R.id.chk_nothave:
                            mycount[position] = 10;// 對應的分數值
                            break;
                        case R.id.chk_sometimes:
                            mycount[position] = 5;
                            break;
                        case R.id.chk_usual:
                            mycount[position] = 1;
                            break;
                        }
                        if (position == viewItems.size() - 1) {
                            /*
                             * 統計分數
                             */
                            int num = 0;
                for (int i = 0; i < mycount.length; i++) {
                                num = num + mycount[i];
                            }
// 跳轉到測試結果頁面
Intent myintent = new Intent(mContext,TestresultAct.class);
myintent.putExtra("num", String.valueOf(num));
                            mContext.startActivity(myintent);
                            mContext.finish();
                        }
                    }
                });
        container.addView(convertView);// 添加頁卡
        return convertView; // 返回的是View對象進行顯示
    }

    // ViewHolder控件容器
    class ViewHolder {
        RadioGroup rapQuestion;
        TextView questionContent;
        TextView txtTopnum;
        TextView txtBottomnum;
        TextView txtTitle;
    }

}

5、還有就是自定義的PointerProgressBar

package com.example.view;

import com.example.viewpagerdemo.R;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

public class PointerProgressBar extends View {
    private int start;

    // 構造方法,帶有attrs自定義屬性
    public PointerProgressBar(Context context, AttributeSet attrs,
            int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        paint = new Paint();
        TypedArray mTypeArray = context.obtainStyledAttributes(attrs,
                R.styleable.RoundProgressBar);
        // 獲取自定義屬性和默認值
        roundColor = mTypeArray.getColor(
                R.styleable.RoundProgressBar_roundColor, Color.GRAY);
        roundProgressColor = mTypeArray.getColor(
                R.styleable.RoundProgressBar_roundProgressColor, Color.RED);
        textColor = mTypeArray.getColor(R.styleable.RoundProgressBar_textColor,
                Color.WHITE);
        textSize = mTypeArray.getDimension(
                R.styleable.RoundProgressBar_textSize, 15);
        roundWidth = mTypeArray.getDimension(
                R.styleable.RoundProgressBar_roundWidth, 5);
        max = mTypeArray.getInteger(R.styleable.RoundProgressBar_max, 100);
        innerRadius = mTypeArray.getDimension(
                R.styleable.RoundProgressBar_innerRadius, 30);
        innerColor = mTypeArray.getColor(
                R.styleable.RoundProgressBar_innerColor, Color.BLUE);
        pointerAngle = mTypeArray.getInteger(
                R.styleable.RoundProgressBar_pointerAngle, 15);
        mTypeArray.recycle();
    }

    public PointerProgressBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PointerProgressBar(Context context) {
        this(context, null);
    }

    /**
     * 畫筆
     */
    private Paint paint;

    /**
     * 內圓半徑
     */
    private float innerRadius;

    /**
     * 內圓顏色
     */
    private int innerColor;

    /**
     * 指針偏角
     */
    private int pointerAngle;

    /**
     * 圓環的顏色
     */
    private int roundColor;

    /**
     * 圓環進度的顏色
     */
    private int roundProgressColor;

    /**
     * 中間進度百分比的字符串顏色
     */
    private int textColor;

    /**
     * 中間進度百分比的字符串大小
     */
    private float textSize;

    /**
     * 圓環的寬度
     */
    private float roundWidth;

    /**
     * 最大進度
     */
    private int max;

    /**
     * 當前進度
     */
    private int progress;

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        start++;
        /**
         * 畫最外層的空心半圓弧
         */
        int center = getWidth() / 2;
        int radius = (int) (center - roundWidth / 2);// 半徑
        paint.setColor(roundColor);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(roundWidth);// 圓弧邊線寬度
        paint.setAntiAlias(true); // 圓弧抗鋸齒
        RectF oval = new RectF(center - radius, center - radius, center
                + radius, center + radius);// 指定圓弧的外輪廓矩形區域
        canvas.drawArc(oval, -180, 180, false, paint);
        /**
         * 畫中間的圓心圓
         */
        paint.setStrokeWidth(0);
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(innerColor);
        canvas.drawCircle(center, center, innerRadius, paint);
        /**
         * 計算各點坐標
         */
        float angle = (float) (start * 18 / 10);// 需求是從-90~90度剛好旋轉了180度
        float cos = (float) Math.cos(Math.PI * angle / 180), sin = (float) Math
                .sin(Math.PI * angle / 180);
        float startX = center - center * cos, startY = center - center * sin;
        float cos1 = (float) Math.cos(Math.PI * (angle + pointerAngle) / 180);
        float sin1 = (float) Math.sin(Math.PI * (angle + pointerAngle) / 180);
        float end1X = center - innerRadius * cos1, end1Y = center - innerRadius
                * sin1;
        float cos2 = (float) Math.cos(Math.PI * (angle - pointerAngle) / 180);
        float sin2 = (float) Math.sin(Math.PI * (angle - pointerAngle) / 180);
        float end2X = center - innerRadius * cos2, end2Y = center - innerRadius
                * sin2;
        Log.e("start ", "angle =" + angle + ",sin = " + sin + ",cos = " + cos
                + ",x=" + startX + ",y=" + startY);
        /**
         * 畫圓環進度
         */
        paint.setColor(roundColor);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(roundWidth);
        paint.setColor(roundProgressColor);
        canvas.drawArc(oval, -180, angle, false, paint);
        /**
         * 畫指針
         */
        paint.setColor(innerColor);
        paint.setStrokeWidth(0);
        paint.setStyle(Paint.Style.FILL);
        Path path = new Path();
        path.moveTo(startX, startY);
        path.lineTo(end1X, end1Y);
        path.lineTo(end2X, end2Y);
        path.close();
        canvas.drawPath(path, paint);
        /**
         * 畫文本進度
         */
        paint.setStrokeWidth(0);
        paint.setColor(textColor);
        paint.setTextSize(textSize);
        paint.setTypeface(Typeface.DEFAULT_BOLD);
        float textWidth = paint.measureText(start + "");
        canvas.drawText(start + "", center - textWidth / 2, center + textSize
                / 2, paint);
        if (start < (int) (((float) progress / (float) max) * 100))
            invalidate();// 不斷做刷新操作
    }

    public float getInnerRadius() {
        return innerRadius;
    }

    public void setInnerRadius(float innerRadius) {
        this.innerRadius = innerRadius;
    }

    public int getRoundColor() {
        return roundColor;
    }

    public void setRoundColor(int roundColor) {
        this.roundColor = roundColor;
    }

    public int getRoundProgressColor() {
        return roundProgressColor;
    }

    public void setRoundProgressColor(int roundProgressColor) {
        this.roundProgressColor = roundProgressColor;
    }

    public int getTextColor() {
        return textColor;
    }

    public void setTextColor(int textColor) {
        this.textColor = textColor;
    }

    public float getTextSize() {
        return textSize;
    }

    public void setTextSize(float textSize) {
        this.textSize = textSize;
    }

    public float getRoundWidth() {
        return roundWidth;
    }

    public void setRoundWidth(float roundWidth) {
        this.roundWidth = roundWidth;
    }

    public synchronized int getMax() {
        return max;
    }

    public synchronized void setMax(int max) {
        if (max < 0)
            throw new IllegalArgumentException("max not less than 0");
        this.max = max;
    }

    public synchronized int getProgress() {
        return progress;
    }

    public synchronized void setProgress(int progress) {
        if (max < 0)
            throw new IllegalArgumentException("progress not less than 0");
        if (progress > max)
            progress = max;
        if (progress <= max) {
            this.progress = progress;
            postInvalidate();
        }
    }

    public int getInnerColor() {
        return innerColor;
    }

    public void setInnerColor(int innerColor) {
        this.innerColor = innerColor;
    }

}

大概就是這樣了,我覺得問題的思路以及導火索就是使用慣了Sqlserver數據庫,一般數據庫分析操作都在裡面,然後就想著能這麼操縱Sqlite數據庫,緊接著,PagerAdapter中傳入一組View的集合,instantiateItem方法中就是返回了一個View的對象,比普通適配器多的是多了一個ViewGroup,顧名思義,就是一個View的容器,實例化後add進去了。然後就是美工需要的效果,相鄰頁面需要部分顯示,並設置透明度進行區分,還有就是未答題就提交的情況,規定了當前題目未作答的情況下不可翻頁,這就引入了需要重寫Viewpager中的事件分發的方法dispatchTouchEvent,傳入Boolean值進行控制是否可以滑動。總得來說,實現地比較流暢,但是又很多細節是自己需要注意的。合理的需求是鍛煉,不合理的需求是磨練啊。。。回頭看看,所有的磨練都是鍛煉。。。那麼繼續鍛煉。。。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved