我正在为从 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>