2014-12-05 9 views
6

Ho 2 sapori - paidapp e freeapp. L'unica differenza che paidapp ha 1 pulsante in più su MainActivity, ad esempio "paidbutton". paidapp ha il proprio layout con il pulsante android:id="@+id/paidbutton" e il layout per freeapp non ha questo pulsante.Android flavor: impossibile trovare la variabile di simbolo nel file R

Nel codice usa questo:

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

Ma ho un errore cannot find symbol variable in findViewById(R.id.paidbutton);

Come risolvere questo problema senza clonazione MainActivity.java in entrambi i sapori?

EDIT1 - aggiungere ulteriori esempi di codice:

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> 

/app/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 - ho trovato qualche soluzione alternativa utilizzando la riflessione, ma ancora alla ricerca di una soluzione normale:

invece di View paidbutton = findViewById(R.id.paidbutton); ho usato View paidbutton = findViewById(getIdFromRId("paidbutton"));

dove 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

Affrontare lo stesso errore, ma questo sembra un comportamento previsto perché quando passiamo a una particolare 'build variant (flavor)', quel sapore di risorse specifiche vengono caricate su da qui l'errore IDE non trova il simbolo. Hai ** due opzioni ** 1. o metti entrambi i pulsanti in activity_main e usa un file di layout da main (non è necessario per la versione specifica di sapore) e nascondi/mostra i pulsanti sulla base dei sapori in fase di esecuzione. 2. copia il tuo 'MainActivity.java' in entrambi i gusti! –

risposta

10

Se non si dispone di un elemento di layoutnel gusto del prodotto freeapp, è possibile semplicemente dichiarare l'elemento id corrispondente in uno dei file xml di risorsa nella cartella sapore del prodotto freeapp.Per esempio creare il file contenente src/freeapp/res/values/ids.xml:

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

Dopo aver fatto che non avrete problemi con la compilazione di codice comune, in quanto il simbolo R.id.paidbutton verrà definito per entrambi i sapori dei prodotti. La chiamata findViewById() restituirà l'elemento di layout reale nel build paidapp e restituirà null nel build freeapp.

0

Puoi inserire il tuo tag XML paidbutton e le tue importazioni della classe MainActivity.java per favore.

Stai forse utilizzando l'importazione risorsa sbagliata come import android.R; invece di import my_package.R;

+0

Non ho importazione R nelle importazioni – anber

+0

Dove si trova la funzione nel codice? Prima o dopo il metodo setContentView()? Il compilatore non riesce a trovare il simbolo R perché stai cercando di usarlo prima della sua inizializzazione. –

+0

quale funzione? – anber

1

È necessario il caso clausola del sul creare e quindi aggiungere il setContentView, in modo da qualcosa come questo:

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); 
} 

o potrebbe eventualmente usare un layout per entrambi e semplicemente rendere invisibile il pulsante

Spero che questo aiuti

+0

Perché ho bisogno di activity_main_paid e activity_main_paid? Ho appena activity_main in entrambi i sapori – anber

+0

questi sono solo i diversi layout, si usa solo una mainactivity, e lì si decide quale layout si desidera utilizzare – glm9637

+0

Sembra che funzioni, ma uccide l'idea di sapori con diversi set di origine, dovrei preoccuparsi di quale xml sarà chousen manualmente invece di androidPlugin – anber

Problemi correlati