2014-12-05 2 views
6

У меня есть 2 варианта - платный и бесплатный. Единственная разница в том, что paidapp имеет еще 1 кнопку на MainActivity, скажем "paidbutton". paidapp имеет свой собственный макет с кнопкой android:id="@+id/paidbutton", а макет для freeapp не имеет этой кнопки.Иконки Android - не может найти символьную переменную в файле R

В коде я использую это:

if (BuildConfig.FLAVOR.equals("paidapp")) { 
      View paidbutton = findViewById(R.id.paidbutton); 
      paidbutton.setOnClickListener(new OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        //... 
       } 
      }); 
} 

Но у меня есть ошибка cannot find symbol variable в findViewById(R.id.paidbutton);

Как решить эту проблему без клонирования MainActivity.java в обоих ароматов?

EDIT1 - добавить больше примеров кода:

Gradle:

productFlavors { 
    paidapp { 
    } 
    freeapp { 
    } 
} 

/app/src/main/res/layout/activity_main.xml

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

    <Button 
     android:id="@+id/goNext" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Go next" /> 

</LinearLayout> 

/приложение/src/paidapp/res/layout/activity_main.xml

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

    <Button 
     android:id="@+id/goNext" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Go next" /> 

    <Button 
     android:id="@+id/paidbutton" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="See more" /> 


</LinearLayout> 

/app/src/main/java/company/com/myapplication/MainActivity.java

package company.com.myapplication; 

import android.app.Activity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.Toast; 


public class MainActivity extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     View goNext = findViewById(R.id.goNext); 
     goNext.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       Toast.makeText(MainActivity.this, "goNext click", Toast.LENGTH_SHORT).show(); 
      } 
     }); 

     if (BuildConfig.FLAVOR.equals("paidapp")) { 
      View paidbutton = findViewById(R.id.paidbutton); 
      paidbutton.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        Toast.makeText(MainActivity.this, "paidapp click", Toast.LENGTH_SHORT).show(); 
       } 
      }); 
     } 
    } 

} 

EDIT2 - Я нашел обходной путь с помощью отражения, но до сих пор ищу нормальное решение:

вместо View paidbutton = findViewById(R.id.paidbutton); я использовал View paidbutton = findViewById(getIdFromRId("paidbutton"));

где getIdFromRId является:

private int getIdFromRId(String idName) { 
    int id = 0; 
    try { 
     Class c = R.id.class; 
     Field field = c.getField(idName); 
     id = field.getInt(null); 
    } catch (Exception e) { 
     // do nothing 
    } 
    return id; 
} 
+0

Опознавая ту же ошибку, но это кажется ожидаемым поведением, потому что, когда мы переходим к конкретному «варианту сборки (вкусу)», эти специфические ресурсы запаса загружаются, следовательно, IDE дает ошибку, не может найти символ. У вас есть ** два варианта ** 1. либо вы помещаете обе кнопки в activity_main, либо используете один файл макета из основного (не нужно для конкретной версии) и скрываете/показываете кнопки на основе вкусов во время выполнения. 2. Скопируйте свой 'MainActivity.java' внутри обоих ароматов! –

ответ

10

Если у вас нет paidbutton элементов макета вообще в цвете продукта freeapp, вы можете просто объявить соответствующий элемент id в одном из ваших xml-файлов ресурсов в freeapp папке с ароматом продукта.Например создать файл, содержащий src/freeapp/res/values/ids.xml:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <item name="paidbutton" type="id"/> 
</resources> 

После этого, что вы не будете иметь никаких проблем с составлением общего кода, так как символ R.id.paidbutton будет определяться как для вкуса продукта. findViewById() вызов вернет реальный элемент макета в paidapp build и вернет значение null в freeapp build.

0

Можете ли вы поместить свой XML-тег paybutton и импортировать класс MainActivity.java.

Вы, возможно, используя неправильный импорт ресурсов как import android.R; вместо import my_package.R;

+0

У меня нет импорта R в импорте – anber

+0

Где ваша функция? До или после метода setContentView()? Компилятор не может найти символ R, потому что вы пытаетесь использовать его перед его инициализацией. –

+0

который функция? – anber

1

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

if (BuildConfig.FLAVOR.equals("paidapp")) { 
     setContentView(R.layout.activity_main_paid); 
     View paidbutton = findViewById(R.id.paidbutton); 
     paidbutton.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       //... 
      } 
     }); 
} 
else{ 
    setContentView(R.layout.activity_main_free); 
} 

или могли бы использовать один макет для обоих и просто сделать невидимую кнопку

Я надеюсь, что это помогает

+0

Зачем мне нужна activity_main_paid и activity_main_paid? У меня только Activity_main в обоих вариантах – anber

+0

это просто разные макеты, вы используете только одну mainactivity, и там вы решаете, какой макет вы хотите использовать. – glm9637

+0

Похоже, что он сработает, но он убьет идею флейворов с помощью разных исходных наборов, я должен забота о том, какой xml будет chousen вручную вместо androidPlugin – anber