wie man auf die zeichnbaren Ressourcen nach Namen in Android zugreift

72

In meiner Anwendung muss ich einige Bitmap-Drawables irgendwo abrufen, wo ich die Referenz nicht behalten möchte R. Also erstelle ich eine Klasse DrawableManager, um die Drawables zu verwalten.

public class DrawableManager {
    private static Context context = null;

    public static void init(Context c) {
        context = c;
    }

    public static Drawable getDrawable(String name) {
        return R.drawable.?
    }
}

Dann möchte ich das Drawable irgendwo wie folgt mit Namen erhalten (das car.png wird in die res / drawables eingefügt):

Drawable d= DrawableManager.getDrawable("car.png");

Wie Sie jedoch sehen können, kann ich nicht über den Namen auf die Ressourcen zugreifen:

public static Drawable getDrawable(String name) {
    return R.drawable.?
}

Irgendwelche Alternativen?

hguser
quelle

Antworten:

163

Beachten Sie, dass Ihr Ansatz fast immer die falsche Vorgehensweise ist (es ist besser, den Kontext an das Objekt selbst zu übergeben, das das Drawable verwendet, als Contextirgendwo eine Statik zu behalten ).

Wenn Sie dynamisch zeichnbares Laden ausführen möchten, können Sie getIdentifier verwenden :

Resources resources = context.getResources();
final int resourceId = resources.getIdentifier(name, "drawable", 
   context.getPackageName());
return resources.getDrawable(resourceId);
ianhanniballake
quelle
1
better to pass the context into the object itself that is using the drawable than keeping a static Context somewhereHallo, kannst du mir mehr erzählen?
hguser
1
@hguser - der Grund , warum Sie wollen würde Drawablees auf dem Bildschirm angezeigt werden - jede Ansicht / activity / Fragment eine hat Contextmit ihm verbunden - Pass , dass Contextin Ihrer getDrawableMethode.
Ianhanniballake
1
Ich kann das irgendwie nicht zum Laufen bringen. Meine Ressourcen-ID ist auch dann 0, wenn das Drawable verfügbar ist und ich den richtigen Kontext übergebe.
Pratik Mandrekar
2
@PratikMandrekar - Angenommen, Sie versuchen, eine Ressource zu erhalten, wie R.drawable.your_imageSie sie verwenden möchten. resource.getIdentifier("your_image", "drawable", context.getPackageName())Ohne bestimmten Code ist es schwer zu erkennen, was falsch ist.
Ianhanniballake
Beachten Sie, dass Ihr Ressourcenname am Ende keine Erweiterung haben sollte (zumindest für Bilder), andernfalls ist Ihre Ressourcen-ID 0. Übergeben Sie nicht "picture.jpg" als Namen, sondern nur "Bild".
Michael Abyzov
23

Sie könnten so etwas tun.

public static Drawable getDrawable(String name) {
    Context context = YourApplication.getContext();
    int resourceId = context.getResources().getIdentifier(name, "drawable", YourApplication.getContext().getPackageName());
    return context.getResources().getDrawable(resourceId);
}

Um von überall auf den Kontext zuzugreifen, können Sie die Anwendungsklasse erweitern.

public class YourApplication extends Application {

    private static YourApplication instance;

    public YourApplication() {
        instance = this;
    }

    public static Context getContext() {
        return instance;
    }
}

Und ordnen Sie es Ihrem Manifest applicationTag zu

<application
    android:name=".YourApplication"
    ....
ssantos
quelle
3
Danke, ich weiß nie, dass ich den Kontext so vorher bekommen kann. Es scheint, dass es die Codes sauberer machen wird.
hguser
Das Erhalten eines Contextauf diese Weise, anstatt es weiterzugeben, ist schlecht für die Testbarkeit. Um beispielsweise eine aufrufende Methode zu YourApplication.getContext()testen, müsste der Test YouApplicationzuerst instanziiert werden YourApplication.getContext(), damit nicht null zurückgegeben wird. Das Erstellen von Globals in Form von Statik ist im Allgemeinen eine schlechte Praxis.
spaaarky21
8

Bildinhalt ändern:

    ImageView image = (ImageView)view.findViewById(R.id.imagenElement);
    int resourceImage = activity.getResources().getIdentifier(element.getImageName(), "drawable", activity.getPackageName());
    image.setImageResource(resourceImage);
Raul
quelle
1

Kotlin benutzen

fun Context.getResource(name:String): Drawable? {
    val resID = this.resources.getIdentifier(name , "drawable", this.packageName)
    return ActivityCompat.getDrawable(this,resID)
}

Ich habe es als Erweiterungsfunktion geschrieben, damit es an jeder Stelle im Code verwendet werden kann.

Hinweis: context.getResources().getDrawable(resourceId);ist in Java veraltet .

Hinweis : Name der Datei, ist Name ohne Erweiterungen, zum Beispiel "a.png" Name ist "a" .

Mahmoud Mabrok
quelle
0

wenn Sie int resouce benötigen

 Resources resources = context.getResources();
 int resourceId = resources.getIdentifier("eskb048", "drawable",context.getPackageName());
 // return like: R.drawable.eskb048.png

Wenn Sie Drawable Check benötigen, ist die erste Antwort für alle richtig

RahmanRezaee
quelle
0

Sie können so erreichen

int resourceId = getResources().getIdentifier("your_drawable_name", "drawable", getPackageName());

Legen Sie die Ressourcen- ID in Imageview fest

imageView.setImageResource(resourceId);
Manasranjan
quelle
Können Sie erklären, wie diese Antwort etwas hinzufügt, was die anderen nicht haben? (Besonders das von Raul !)
Adrian Mole