5

Io uso Android Studio e hanno creato la mia vista personalizzata:utilizzo personalizzato in visualizzazioni personalizzate, mentre nel layout anteprima

<LinearLayout 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     android:orientation="vertical" 
     android:gravity="center_horizontal|center_vertical" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_margin="4dp"> 

    <Button 
      android:id="@+id/dateTile" 
      android:layout_height="@dimen/date_tile_height" 
      android:layout_width="@dimen/date_tile_width" 
      android:background="@drawable/bg_january"/> 

    <CheckBox 
      android:id="@+id/dateTileCheckbox" 
      android:button="@drawable/check_green" 
      android:layout_width="30dp" 
      android:layout_height="30dp" 
      android:layout_marginLeft="15dp" 
      android:layout_marginTop="-20dp" 
      android:focusable="false"/> 

    <TextView 
      android:id="@+id/dateTileLabel" 
      android:layout_width="wrap_content" 
      android:layout_marginTop="-10dp" 
      android:layout_height="wrap_content"/> 

</LinearLayout> 

in aggiunta ho definito il seguente attributi personalizzati

<resources> 
    <declare-styleable name="DateTileView"> 
     <attr name="monthLabel" format="string" localization="suggested" /> 
     <attr name="tileBackground" format="reference" /> 
    </declare-styleable> 
</resources> 

Io uso il attributi personalizzati per definire l'etichetta e lo sfondo della tessera della data nel costruttore in questo modo.

public class DateTileView extends LinearLayout 
{ 
//.... 
//.... 
public DateTileView(Context context, AttributeSet attrs) 
    { 
     super(context, attrs); 
     TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DateTileView, 0, 0); 

     String monthLabel = a.getString(R.styleable.DateTileView_monthLabel); 
     Drawable monthBG = a.getDrawable(R.styleable.DateTileView_tileBackground); 

     LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     inflater.inflate(R.layout.custom_view_date_tile, this, true); 

     TextView dateTileLabel = (TextView) findViewById(R.id.dateTileLabel); 
     dateTileLabel.setText(monthLabel); 

     Button dateTileButton = (Button) findViewById(R.id.dateTile); 
     dateTileButton.setBackgroundDrawable(monthBG); //TODO: remove deprecated use if JELLY BEAN 

     a.recycle(); 
    } 
//... 
//... 
} 

quando si utilizza la piastrella data in un altro XML mi arrivano questo errore:

The following classes could not be instantiated: 
- com.endilo.widget.DateTileView (Open Class, Show Exception) 
    Tip: Use View.isInEditMode() in your custom views to skip code 
    or show sample data when shown in the IDE 

Exception Details java.lang.NullPointerException   at 
com.endilo.widget.DateTileView.<init>(DateTileView.java:35)   at 
java.lang.reflect.Constructor.newInstance   at 
android.view.LayoutInflater.rInflate_Original   at 
android.view.LayoutInflater_Delegate.rInflate   at 
android.view.LayoutInflater.rInflate   at 
android.view.LayoutInflater.rInflate_Original   at 
android.view.LayoutInflater_Delegate.rInflate   at 
android.view.LayoutInflater.rInflate   at 
android.view.LayoutInflater.rInflate_Original   at 
android.view.LayoutInflater_Delegate.rInflate   at 
android.view.LayoutInflater.rInflate   at 
android.view.LayoutInflater.inflate   at android.view.LayoutInflater.inflate 

L'applicazione funziona bene, ma l'anteprima non lo farà. Esiste un modo per caricare attributi personalizzati per mostrare un'anteprima con attributi personalizzati?

+0

stesso problema qui, qualche soluzione? –

risposta

-1

Non è possibile eseguire tutto ciò che si ha nella riga 35 quando l'applicazione non è in esecuzione, poiché la modalità di progettazione otterrà un riferimento null per un oggetto che viene solo istanziato sul runtime.

Si deve evitare l'esecuzione di quelli della modalità di progettazione utilizzando isInEditMode(), come qui:

if(!isInEditMode()) { 
    whatever there is in the line 35 of your class 
} 

Se dovete effettuare qualche cambiamento nella vista, e si desidera che sia visibile su il progettista, ignorare OnDraw(), come qui:

@Override 
protected void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 

    TypedArray a = this.getContext().obtainStyledAttributes(attrs, R.styleable.DateTileView, 0, 0); 

    String monthLabel = a.getString(R.styleable.DateTileView_monthLabel); 
    Drawable monthBG = a.getDrawable(R.styleable.DateTileView_tileBackground); 

    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    inflater.inflate(R.layout.custom_view_date_tile, this, true); 

    TextView dateTileLabel = (TextView) findViewById(R.id.dateTileLabel); 
    dateTileLabel.setText(monthLabel); 

    Button dateTileButton = (Button) findViewById(R.id.dateTile); 
    dateTileButton.setBackgroundDrawable(monthBG); //TODO: remove deprecated use if JELLY BEAN 

    a.recycle(); 
}