文档参见:react-native中文网
一、创建自己的View
public class ReactMaterialView extends View {
/** * 文本 */
private String mTitleText;
/** * 文本的颜色 */
private String mTitleTextColor="#ff0000";
/** * 文本的大小 */
private int mTitleTextSize;
/** * 绘制时控制文本绘制的范围 */
private Rect mBound;
private Paint mPaint;
//构造方法
public ReactMaterialView(Context context,AttributeSet attrs){
this(context,attrs,0);
Log.i("construct","构造方法1");
}
//构造方法
public ReactMaterialView(Context context)
{
this(context,null);
Log.i("construct","构造方法2");
}
/** * 获得我自定义的样式属性 * * @param context * @param attrs * @param defStyle */
public ReactMaterialView(Context context,AttributeSet attrs,int defStyle)
{
super(context,defStyle);
/** * 获得我们所定义的自定义样式属性 */
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,R.styleable.ReactMaterialView,defStyle,0);
int n = a.getIndexCount();
for (int i = 0; i < n; i++)
{
int attr = a.getIndex(i);
switch (attr)
{
case R.styleable.ReactMaterialView_titleText:
mTitleText = a.getString(attr);
break;
case R.styleable.ReactMaterialView_titleTextColor:
// 默认颜色设置为黑色
mTitleTextColor = Integer.toHexString(a.getColor(attr,Color.BLACK));
break;
case R.styleable.ReactMaterialView_titleTextSize:
// 默认设置为16sp,TypeValue也可以把sp转化为px
mTitleTextSize = a.getDimensionPixelSize(attr,(int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP,16,getResources().getDisplayMetrics()));
break;
}
}
a.recycle();
Log.i("construct","构造方法3");
/** * 获得绘制文本的宽和高 */
mPaint = new Paint();
mBound = new Rect();
}
@Override
protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec,heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas)
{
mPaint.setTextSize(mTitleTextSize);
mPaint.setColor(Color.YELLOW);
canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),mPaint);
mPaint.getTextBounds(mTitleText,mTitleText.length(),mBound);
mPaint.setColor(Color.parseColor(mTitleTextColor));
float x=getWidth() / 2 - mBound.width() / 2;
float y= getHeight() / 2 + mBound.height() / 2;
Log.i("construct",this.mTitleText+mTitleTextColor+this.mTitleTextSize+";X:"+x+",Y:"+y);
canvas.drawText(mTitleText,x,y,mPaint);
}
//给当前对象的属性赋值,方便后面调用
protected void setmTitleText(String mTitleText){this.mTitleText=mTitleText;}
protected void setmTitleTextColor(String mTitleTextColor){
this.mTitleTextColor=mTitleTextColor;
}
protected void setmTitleTextSize(int mTitleTextSize){
this.mTitleTextSize=mTitleTextSize;
}
}
二、创建ViewManager的子类
例子中的代码如下:
public class ReactMaterialdrawerManager extends SimpleViewManager<ReactMaterialView> {
//定义名字,必须的部分
public static final String RTCNAME="RCTMaterialView";
//getName方法返回的名字会用于在JavaScript端引用这个原生视图类型
@Override
public String getName() {
return RTCNAME;
}
//实现方法createViewInstance,用来生成上面的自定义view的对象
@Override
protected ReactMaterialView createViewInstance(ThemedReactContext reactContext) {
return new ReactMaterialView(reactContext);
}
// 通过@ReactProp(或@ReactPropGroup)注解来导出属性的设置方法
@ReactProp(name = "titleText")
public void setmTitleText(ReactMaterialView view,@Nullable String titleText) {
Log.i("ViewManager","settitleText");
view.setmTitleText(titleText);
}
@ReactProp(name = "titleTextColor")
public void setmTitleTextColor(ReactMaterialView view,@Nullable String titleTextColor) {
Log.i("ViewManager","settitleTextColor");
view.setmTitleTextColor(titleTextColor);
}
@ReactProp(name = "titleTextSize")
public void setmTitleTextSize(ReactMaterialView view,int titleTextSize) {
Log.i("ViewManager","setTextSize");
view.setmTitleTextSize(titleTextSize);
}
}
三、注册ViewManager
这里我们使用第三个类
/** * Created by Jing on 15/9/22. */
public class CustomReactPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
//最后一步就是把视图控制器注册到应用中。这和原生模块的注册方法类似,唯一的区别是我们把它放到createViewManagers方法的返回值里。
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
List<ViewManager> result = new ArrayList<ViewManager>();
result.add(new ReactMaterialdrawerManager());
return result;
}
}
另外还需要在创建reactview对象的时候声明下引入该类,如下:
mReactRootView = new ReactRootView(this);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")
.addPackage(new MainReactPackage())
.addPackage(new CustomReactPackage())//这里引入了上面的类
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
mReactRootView.startReactApplication(mReactInstanceManager,"HelloWorld",null);
setContentView(mReactRootView);
四、以上完成之后就可以在js中声明调用了,方式如下:
//定义
var attrs= {
name: 'RCTView',propTypes: {
...View.propTypes,titleText: PropTypes.string,titleTextColor: PropTypes.string,titleTextSize: PropTypes.number,},};
//前提是requireNativeComponent这个组件也得引入
var RCTTextView = requireNativeComponent('RCTMaterialView',attrs);
//使用
<RCTTextView
style={{flex:1,width:100,height:100}}
titleText={"好好计划"}
titleTextColor={"#317ef3"}
titleTextSize={50}
/>