创建自定义视图并重用同一视图

时间:2018-11-29 15:38:35

标签: java android android-layout

我有一个表格布局,其中包含五个表格行。每个表格行都有一个呈现某些图形的自定义视图和一个自定义textview。我的布局看起来像下面的

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TableRow
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1">

    <com.company.views.FirstView
        android:id="@+id/firstView"
        android:layout_height="match_parent"
        android:layout_width="0dp"
        android:layout_weight=".80"
        android:background="#000000" />
    <com.company.views.FirstTextView
        android:id="@+id/firstTextView"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight=".20"
        android:background="#000000"
        android:textColor="#00FF00"
        android:gravity="center"
        android:textStyle="bold|italic"
        android:textSize="40sp"
        android:inputType="number"
        android:digits="1234567890"
        android:cursorVisible="false"
        android:scrollbars = "vertical"/>
</TableRow>
<TableRow
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1">
    <com.company.views.SecondView
        android:id="@+id/secondView"
        android:layout_height="match_parent"
        android:layout_width="0dp"
        android:layout_weight=".80"
        android:background="#000000" />
    <com.company.views.SecondTextView
        android:id="@+id/secondTextView"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight=".20"
        android:background="#000000"
        android:textColor="#FFFF00"
        android:gravity="center"
        android:textStyle="bold|italic"
        android:textSize="40sp"
        android:inputType="number"
        android:digits="1234567890"
        android:cursorVisible="false"
        android:scrollbars = "vertical"/>
</TableRow>
</TableLayout>

上面的代码可以正常工作(为了解释起见,我已经删除了一些代码),但是问题是我的firstview和secondview在功能和代码上看起来非常相似,而firstTextView和secondTextView也是如此。

问题是,我没有一个不同的自定义视图,而是只需要一个自定义视图并重复使用它,因此布局如下所示:

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
android:layout_height="match_parent">
<TableRow
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1">

    <com.company.views.FirstView
        android:id="@+id/firstView"
        android:layout_height="match_parent"
        android:layout_width="0dp"
        android:layout_weight=".80"
        android:background="#000000" />
    <com.company.views.FirstTextView
        android:id="@+id/firstTextView"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight=".20"
        android:background="#000000"
        android:textColor="#00FF00"
        android:gravity="center"
        android:textStyle="bold|italic"
        android:textSize="40sp"
        android:inputType="number"
        android:digits="1234567890"
        android:cursorVisible="false"
        android:scrollbars = "vertical"/>
</TableRow>
<TableRow
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1">
    <com.company.views.FirstView
        android:id="@+id/secondView"
        android:layout_height="match_parent"
        android:layout_width="0dp"
        android:layout_weight=".80"
        android:background="#000000" />
    <com.company.views.FirstTextView
        android:id="@+id/secondTextView"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight=".20"
        android:background="#000000"
        android:textColor="#FFFF00"
        android:gravity="center"
        android:textStyle="bold|italic"
        android:textSize="40sp"
        android:inputType="number"
        android:digits="1234567890"
        android:cursorVisible="false"
        android:scrollbars = "vertical"/>
</TableRow>
</TableLayout>

问题在于,当我从firstTextView java类中执行以下操作

private void init(AttributeSet attrs, int defStyle) {
    textView = (TextView)findViewById(R.id.firstTextView);
    textView.setText("My Awesome Text");;
}

代码因膨胀异常而中断。我被困在这里,因为我不知道自己在做什么错。还有其他方法可以达到预期的结果。还是我缺少明显的东西。

我的FirstTextView看起来如下

public class FirstTextView extends AppCompatTextView {
private int spinnerText=120;
private float oldY=0;
private TextView textView;
private Context context;
private PopupWindow mPopupWindow;

public FirstTextView(Context context) {
    super(context);
    this.context = context;
    init(null, 0);
}

public FirstTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.context = context;
    init(attrs, 0);

}

public FirstTextView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    this.context = context;
    init(attrs, defStyle);
}

private void init(AttributeSet attrs, int defStyle) {
    //cant do that as the findviewbyid return null
    textView = (TextView)findViewById(R.id.firstView);
    textView.setOnTouchListener(handleTouch);
    // Here i want to find which textview firstView or SecondView. 
    //if(firstview)
       //textView.setText(""+Physiology.getInstance().Model1.getValue());
    //else 
      //textView.setText(""+Physiology.getInstance().Model2.getValue());  
     textView.setText(""+Physiology.getInstance().Model2.getValue());
}

@Override
public void setText(CharSequence text, BufferType type) {
    String newText="";
    if(text.length()>0){
        newText=String.valueOf(text);
        int textasNumber=Integer.valueOf(newText);
        Physiology.getInstance().mBloodPressure.setSystolic(textasNumber);
        newText= Physiology.getInstance().mBloodPressure.getSystolic() + "/" +  (int)Physiology.getInstance().mBloodPressure.mDiastolic;
    }

    super.setText(newText,type);
}

public void onTextViewClick(View v) {
    // Initialize a new instance of LayoutInflater service
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);

    // Inflate the custom layout/view
    NumberPadView customView = (NumberPadView) inflater.inflate(R.layout.number_popup,null);

    // Initialize a new instance of popup window
    mPopupWindow = new PopupWindow(
            customView,
            RelativeLayout.LayoutParams.WRAP_CONTENT,
            RelativeLayout.LayoutParams.WRAP_CONTENT
    );

    customView.init(Physiology.getInstance().mBloodPressure.getSystolic(),mPopupWindow,this);

    // Finally, show the popup window at the center location of root
    mPopupWindow.showAtLocation(v, Gravity.CENTER,0,0);
}
  }

2 个答案:

答案 0 :(得分:2)

由于自定义视图扩展了TextView,因此无需执行findViewById。您的对象本身已经是视图。

因此,您只需在init()中调用setText(“ even awesomer”);

您的代码中断了,因为findViewById返回null,然后您得到一个NPE尝试在其上调用setText()。

要在视图中区分视图,只需使用getId()。

但是从您的问题来看,我认为您只想像其他视图一样对待自定义视图。在这种情况下,请对其他视图执行操作。在Activity的onCreate()中,在setContentView()之后,执行

firstView = findViewById(R.id.firstView);
firstTextView = findViewById(R.id.firstTextView);
secomdView = findViewById(R.id.secondView);
secondTextView = findViewById(R.id.secondTextView);

firstView.setText("Hi there");
...

答案 1 :(得分:1)

如果文本是您要更改的 only 东西,我只需将文本直接放入XML文件中即可:

<com.company.views.FirstTextView
    android:id="@+id/firstTextView"
    android:text="my first text
    .../>
<com.company.views.FirstTextView
    android:id="@+id/secondTextView"
    android:text="my second text
    .../>

即使您使用TextView的子类,仍可以照常使用其属性。


如果需要执行特殊操作,还可以从视图本身中查询视图ID:

private void init(AttributeSet attrs, int defStyle) {
    if (getId() == R.id.firstTextView) {
        ...
    } else if (getId() == R.id.secondTextView) {
        ...
    }
    ...
}

总的来说,这不是一个好主意,因为您的视图应该(通常)在不知道其自身ID是什么的情况下工作,但是如果您需要它,您仍然可以这样做。