0

Я создал пользовательский вид RelativeLayout, который я надуваю с помощью merge тегов.
В этом пользовательском представлении у меня есть кнопка, которую я хочу, чтобы она что-то делала.
Я пробовал много вещей, но кнопка просто отказывается щелкнуть.Пользовательское представление Android с кнопкой не кликается

Странная часть, я могу найти виды и изменить их видимость просто отлично.

Можно ли щелкнуть по кнопке таким образом, или это должно быть сделано по-другому?

То, что я пробовал:

  • Anonymous InnerClass для onClickListener
  • атрибута XML для onClick
  • View onClick с onClickListener(this)
  • Проверьте, если это интерактивное с кодом (он возвращает истину)
  • Добавлен clickable(true) как для XML, так и для кода.
  • Частный контекст из конструктора вместо getContext()
  • Переехал логика из init() в onFinishInflate()
  • Используется вид с Inflater найти вид на
  • Переход от inflate() к LayoutInflater

Завышенные вида в:

<?xml version="1.0" encoding="utf-8"?> 
<merge 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <TextView 
     android:id="@+id/internet_view_text" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_centerInParent="true" 
     android:text="@string/internet_offline"/> 

    <custom.IconView 
     android:id="@+id/internet_view_icon" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_centerInParent="true" 
     android:text="ICON" 
     android:visibility="invisible" 
     android:layout_below="@+id/internet_view_text"/> 

    <Button 
     android:id="@+id/internet_view_button" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_centerInParent="true" 
     android:text="BUTTON" 
     android:clickable="true" 
     android:layout_below="@+id/internet_view_text"/> 
</merge> 

Соответствующая часть родительского вида:

<custom.NoInternetView 
    android:id="@+id/webview_no_content" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:visibility="invisible" 
    app:automaticReconnect="false"/> 

Класс файла:

public class NoInternetView extends RelativeLayout implements View.OnClickListener { 

    private static final String TAG = NoInternetView.class.getSimpleName(); 

    private static ConnectivityChangeListener listener; 
    private static boolean automaticReconnect; 
    private Context mContext; 
    private View view; 

    private Button button; 

    public NoInternetView(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
     mContext = context; 
     TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NoInternetView, defStyleAttr, 0); 
     automaticReconnect = a.getBoolean(R.styleable.NoInternetView_automaticReconnect, false); 
     a.recycle(); 
     init(); 
    } 

    public NoInternetView(Context context, AttributeSet attrs) { 
     this(context, attrs, 0); 
    } 

    public NoInternetView(Context context) { 
     this(context, null); 
    } 

    @Override 
    protected void onFinishInflate() { 
     Log.d(TAG, "onFinishInflate"); 
     super.onFinishInflate(); 

     button = (Button) view.findViewById(R.id.internet_view_button); 
     button.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       Log.d(TAG, "Clicked on some Button"); 
       if (listener != null && NetworkHelper.hasAccess(getContext())) { 
        listener.connected(); 
       } 
      } 
     }); 
     button.setClickable(true); 

     boolean clicked = button.callOnClick(); 
     Log.d(TAG, "clicked: "+clicked); 

     TextView text = (TextView) view.findViewById(R.id.internet_view_icon); 
     text.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       Log.d(TAG, "Clicked on some TextView"); 
       if (listener != null && NetworkHelper.hasAccess(getContext())) { 
        listener.connected(); 
       } 
      } 
     }); 

     //check if the attribute 'automaticReconnect' is set to true 
     //if so, show an icon instead of a button 
     if (automaticReconnect){ 
      button.setVisibility(INVISIBLE); 
      view.findViewById(R.id.internet_view_icon).setVisibility(VISIBLE); 
     } 

    } 

    public void init(){ 
     Log.d(TAG, "init"); 
     view = LayoutInflater.from(mContext).inflate(R.layout.no_internet_view, this, false); 
    } 

    @Override 
    public boolean dispatchKeyEvent(KeyEvent event) { 
     Log.d(TAG, "something happened?"); 
     return super.dispatchKeyEvent(event); 
    } 

    @Override 
    public void onClick(View v) { 
     Log.d(TAG, "Clicked on Button(TextView)"); 
     if (listener != null && NetworkHelper.hasAccess(getContext())){ 
      listener.connected(); 
     } 
    } 
+1

Почему вы используете здесь тег слияния? Макет, который вы используете здесь, предназначен только для инфляции в CustomView, слияние здесь не требуется. Он работает, если вы замените слияние на тип макета. – Henry

+0

@Henry Я использовал тег слияния, потому что я прочитал эту [ссылку] (http://trickyandroid.com/protip-inflating-layout-for-your-custom-view/), которая показывает дополнительный макет в иерархии, когда вы Не используйте теги слияния. Также, когда я меняю слияние на RelativeLayout, мои TextView и Button не видны. –

+0

Дайте мне пару часов. Я отлажу его и дам вам знать. – Henry

ответ

0

Так что я получил его на работу. Вот что я сделал, чтобы заставить его работать.

  1. Заменить merge тега RelativeLayout, потому что вы раздувание расположения, чтобы показать внутри зрения. Более подробная информация здесь: Android xml merge layout error on inflate

  2. Вы установили android:visibility="invisible", изменить что android:visibility="visible" (Это только, чтобы получить вид виден, вы можете позже изменить его программно)

  3. Добавьте строку ниже в Init() метод вашего NoInternetView. Вы раздуваете макет всеми видами, но только когда вы добавляете это представление, вы сможете его увидеть.

    public void init(){ 
         Log.d(TAG, "init"); 
         view = LayoutInflater.from(mContext).inflate(R.layout.no_internet_view, this, false); 
         this.addView(view);} 
    

После того, как вы закончите с этим, кнопка будет видна, и нажав на кнопку будет кликабельна.Вы можете использовать анонимный onClickListener или сделать представление реализацией onClickListener и переопределить метод onClick(). Все работает.

+0

this.addView (view) вызовет цикл и, в конечном итоге, исключение из памяти. –

+0

Не совсем. Вы создали CustomView, это RelativeLayout. Вам нужно показать что-то на экране, так что вы раздуваете макет в CustomView. Проблема в том, что одного раздувания недостаточно. Вам нужно добавить этот завышенный вид в CustomView. Я думаю, что вы что-то делаете неправильно в другом месте. Я выполнил ваш код после внесения всех этих изменений. Прекрасно работает для меня. – Henry

+0

Не имеет значения, что этот макет загружен в макет фрагмента? –

 Смежные вопросы

  • Нет связанных вопросов^_^