Создание собственного представления и повторное использование одного и того же представления - PullRequest
0 голосов
/ 29 ноября 2018

У меня есть макет таблицы, который состоит из пяти строк таблицы.Каждая строка таблицы имеет пользовательское представление, которое отображает некоторый график и пользовательское текстовое представление.Мой макет выглядит следующим образом:

<?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>

Вышеприведенный код работает (я взял некоторый код для пояснения), но проблема в том, что мое первое и второе представления выглядят очень похожими по функциональности и коду, а такжеТо же самое касается моего 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>

Проблема в том, что, когда из моего java-класса firstTextView я делаю следующее

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 голосов
/ 29 ноября 2018

Если вы хотите изменить текст 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, вы все равно можете использовать его атрибуты как обычно.


Вы также можете запросить идентификатор представления внутри самого представления, если вам нужно сделать что-то особенное:

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

В целом, я бы сказал, что это не очень хорошая идея, поскольку ваши представления должны (в общем) работать, не зная, каков их собственный идентификатор ... но вы все равно можете сделать это, если это то, что вам нужно.

0 голосов
/ 29 ноября 2018

Так как ваши пользовательские представления расширяют TextView, нет необходимости выполнять findViewById.Сам ваш объект уже является представлением.

Таким образом, вы можете просто в своем init () вызвать setText ("даже awesomer");

Ваш код прерывается, потому что findViewById возвращает ноль, и тогда вы получаетеNPE пытается вызвать setText () для этого.

Чтобы провести различие между представлениями в представлении, просто используйте getId ().

Но из ваших вопросов я думаю, что вы просто хотите рассмотреть своиПользовательские виды, как и любой другой вид.В этом случае делайте то, что вы делаете для других видовВ 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");
...
.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...