1

我正在为从 View 扩展的 3D 翻页编写自定义视图。在这个自定义视图中,我为页面的前景和背景声明了两个视图。我已经为页面的每个前景和背景声明了不同的布局。每个布局都有一个 Relativelayout 和其中的一些元素。

在自定义视图中,我膨胀布局并将它们分配给前景和背景视图。

可以看到 RelativeLayout,但布局内的元素未显示。

有人可以建议我如何实现这一目标。卡住了..

我的自定义视图代码:

public class PageCurlView extends View {

    /** Our Log tag */
    private final static String TAG = "PageCurlView";


    private Context myAppContext;



    /** The context which owns us */
    private WeakReference<Context> mContext;


    /** LAGACY The current foreground */
    //private Bitmap mForeground;
    public View mForeground;

    /** LAGACY The current background */
    //private Bitmap mBackground;

    public View mBackground;

        /** LAGACY Current selected page */
    private int mIndex = 0;


    public Integer[] mViewIds = {
            R.layout.view_1,
            R.layout.view_2,
            R.layout.view_3,
            R.layout.view_4,
            R.layout.view_5,
            R.layout.view_6,
            R.layout.view_7,
            R.layout.view_8,
            R.layout.view_9,
            R.layout.view_10

       };

    private int mTotalViews = mViewIds.length;

    //Variables for inline sliders
    public ViewPager mInlinePager;
    public AwesomePagerAdapter mInlineAdapter;

    /**
     * Base
     * @param context
     */
    public PageCurlView(Context context) {
        super(context);
        init(context);
        ResetClipEdge();
    }

    /**
     * Construct the object from an XML file. Valid Attributes:
     * 
     * @see android.view.View#View(android.content.Context, android.util.AttributeSet)
     */
    public PageCurlView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);

        // Get the data from the XML AttributeSet
        {
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PageCurlView);

            // Get data
            bEnableDebugMode = a.getBoolean(R.styleable.PageCurlView_enableDebugMode, bEnableDebugMode);
            mCurlSpeed = a.getInt(R.styleable.PageCurlView_curlSpeed, mCurlSpeed);
            mUpdateRate = a.getInt(R.styleable.PageCurlView_updateRate, mUpdateRate);
            mInitialEdgeOffset = a.getInt(R.styleable.PageCurlView_initialEdgeOffset, mInitialEdgeOffset);
            mCurlMode = a.getInt(R.styleable.PageCurlView_curlMode, mCurlMode);


            // recycle object (so it can be used by others)
            a.recycle();

        }

        ResetClipEdge();
    }

    /**
     * Initialize the view
     */
    private final void init(Context context) {

        myAppContext = context;


        // Cache the context
        mContext = new WeakReference<Context>(context);

        // Base padding
        setPadding(3, 3, 3, 3);

        // The focus flags are needed
        setFocusable(true);
        setFocusableInTouchMode(true);

        mMovement =  new Vector2D(0,0);
        mFinger = new Vector2D(0,0);
        mOldMovement = new Vector2D(0,0);


        // Set the default props, those come from an XML :D



        // Create some sample images

        LayoutInflater inflater = (LayoutInflater)  myAppContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view1 = inflater.inflate(mViewIds[0], null);   
        View view2 = inflater.inflate(mViewIds[1], null); 



        //Fix after coming back from vacation
        //For inline sliders

        mForeground = view1;
        mBackground = view2;

    }


    /**
     * Reset points to it's initial clip edge state
     */


    /**
     * Render the text
     * 
     * @see android.view.View#onDraw(android.graphics.Canvas)
     */
    //@Override
    //protected void onDraw(Canvas canvas) {
    //  super.onDraw(canvas);
    //  canvas.drawText(mText, getPaddingLeft(), getPaddingTop() - mAscent, mTextPaint);
    //}

    //---------------------------------------------------------------
    // Curling. This handles touch events, the actual curling
    // implementations and so on.
    //---------------------------------------------------------------



    /**
     * Swap between the fore and back-ground.
     */
    @Deprecated
    private void SwapViews() {
        /*Bitmap temp = mForeground;
        mForeground = mBackground;
        mBackground = temp;*/

        View temp = mForeground;
        mForeground = mBackground;
        mBackground = temp;
    }

    /**
     * Swap to next view
     */
    private void nextView() { //Sushil need to uncomment
        int foreIndex = mIndex + 1;
        if(foreIndex >= /*mPages.size()*/mTotalViews) {
            //foreIndex = 0;
            foreIndex = mTotalViews-1;
        }
        int backIndex = foreIndex + 1;
        if(backIndex >= /*mPages.size()*/mTotalViews) {
            //backIndex = 0;
            backIndex = mTotalViews-1;
        }
        mIndex = foreIndex;

            setViews(foreIndex, backIndex);
    }

    /**
     * Swap to previous view
     */
    private void previousView() { //Sushil need to uncomment
        Log.i("Sushil", "....previousView()....");
        int backIndex = mIndex;
        int foreIndex = backIndex - 1;
        if(foreIndex < 0) {
            foreIndex = /*mPages.size()*/0;
        }
        mIndex = foreIndex;
        setViews(foreIndex, backIndex);

    }

    /**
     * Set current fore and background
     * @param foreground - Foreground view index
     * @param background - Background view index
     */
    private void setViews(int foreground, int background) {

        LayoutInflater inflater = (LayoutInflater)  myAppContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view1 = inflater.inflate(mViewIds[foreground], null);   
        View view2 = inflater.inflate(mViewIds[background], null); 

        mForeground = view1;//(WebView)mPages.get(foreground);
        mBackground = view2;//(WebView)mPages.get(background);
    }

    //---------------------------------------------------------------
    // Drawing methods
    //---------------------------------------------------------------

    @Override
    protected void onDraw(Canvas canvas) {
        // Always refresh offsets
        mCurrentLeft = getLeft();
        mCurrentTop = getTop();

        // Translate the whole canvas
        //canvas.translate(mCurrentLeft, mCurrentTop);

        // We need to initialize all size data when we first draw the view
        if ( !bViewDrawn ) {
            bViewDrawn = true;
            onFirstDrawEvent(canvas);
        }

        canvas.drawColor(Color.WHITE);

        // Curl pages
        //DoPageCurl();

        // TODO: This just scales the views to the current
        // width and height. We should add some logic for:
        //  1) Maintain aspect ratio
        //  2) Uniform scale
        //  3) ...
        Rect rect = new Rect();
        rect.left = 0;
        rect.top = 0;
        rect.bottom = getHeight();
        rect.right = getWidth();

        // First Page render
        Paint paint = new Paint();

        // Draw our elements
        drawForeground(canvas, rect, paint);
        drawBackground(canvas, rect, paint);

        drawCurlEdge(canvas);

        // Draw any debug info once we are done
        if ( bEnableDebugMode )
            drawDebug(canvas);

        // Check if we can re-enable input
        if ( bEnableInputAfterDraw )
        {
            bBlockTouchInput = false;
            bEnableInputAfterDraw = false;
        }

        // Restore canvas
        //canvas.restore();
        super.onDraw(canvas);
    }

    /**
     * Called on the first draw event of the view
     * @param canvas
     */
    protected void onFirstDrawEvent(Canvas canvas) {

        mFlipRadius = getWidth();

        ResetClipEdge();
        DoPageCurl();
    }

    /**
     * Draw the foreground
     * @param canvas
     * @param rect
     * @param paint
     */
    private void drawForeground( Canvas canvas, Rect rect, Paint paint ) {
        //canvas.drawBitmap(mForeground, null, rect, paint);
        //mForeground.loadUrl("file:///android_asset/WebContent/Section01.html");

        mForeground.layout(rect.left, rect.top, rect.right, rect.bottom);
        mForeground.draw(canvas);


        // Draw the page number (first page is 1 in real life :D 
        // there is no page number 0 hehe)
        //drawPageNum(canvas, mIndex);
    }

    /**
     * Create a Path used as a mask to draw the background page
     * @return
     */
    private Path createBackgroundPath() {
        Path path = new Path();
        path.moveTo(mA.x, mA.y);
        path.lineTo(mB.x, mB.y);
        path.lineTo(mC.x, mC.y);
        path.lineTo(mD.x, mD.y);
        path.lineTo(mA.x, mA.y);
        return path;
    }

    /**
     * Draw the background image.
     * @param canvas
     * @param rect
     * @param paint
     */
    private void drawBackground( Canvas canvas, Rect rect, Paint paint ) {
        Path mask = createBackgroundPath();

        // Save current canvas so we do not mess it up
        canvas.save();
        canvas.clipPath(mask);
        //canvas.drawBitmap(mBackground, null, rect, paint);
        //mBackground.loadUrl("file:///android_asset/WebContent/Section01.html");
        mBackground.layout(rect.left, rect.top, rect.right, rect.bottom);
        mBackground.draw(canvas);



        // Draw the page number (first page is 1 in real life :D 
        // there is no page number 0 hehe)
        drawPageNum(canvas, mIndex);

        canvas.restore();
    }

}

我的布局文件之一:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">


<TextView 
    android:id="@+id/sampletextview"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@color/red"
    android:text="VIEW 1" />

</RelativeLayout>
4

2 回答 2

2

“你这样做是错的”

您的自定义视图包含一堆其他视图,因此从逻辑上讲,它应该ViewGroup(或它的子类)具有正确的实现,而不仅仅是View.

于 2013-10-11T11:36:08.210 回答
-1

膨胀视图后设置布局参数。

RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams([width], [heigth]);
//assign additional params like below, above, to right or to left or others relative layout params
inflatedView.setLayoutParams(lp);
于 2013-10-11T06:41:57.733 回答