您的位置:首页 > Web前端 > React

React-native自定义安卓组件

2017-01-10 17:05 896 查看
文档参见: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, attrs, 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, 0, 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}
/>


五、以上就可以完成一个简单的可修改内容和字体颜色和字号的textview了,效果如下:



打包的代码:点这
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: