React-native自定义安卓组件

文档参见: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了,效果如下:

这里写图片描述
打包的代码:点这

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值