加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

React-native自定义安卓组件

发布时间:2020-12-15 07:37:15 所属栏目:百科 来源:网络整理
导读:文档参见:react-native中文网 一、创建自己的View public class ReactMaterialView extends View { /** * 文本 */ private String mTitleText; /** * 文本的颜色 */ private String mTitleTextColor= "#ff0000" ; /** * 文本的大小 */ private int mTitleTex

文档参见: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}
          />

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


打包的代码:点这

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读