2011-02-07 10 views
23

Jestem nowy w programowaniu Android i próbuję to rozgryźć;Android: Rysowanie kanwy do ImageView

W moim układzie mam TextView, ImageView, guziki, wszystko na pionowo LinearLayout.

chcę, aby móc dynamicznie rysować okręgi w ImageView, bez zakłócania resztę układu (TextView/przycisk). Próbuję utworzyć płótno i użyć funkcji drawcircle w obszarze roboczym do ustawienia położenia okręgu. A potem narysuj to płótno do mojego obrazu w jakiś sposób. Nie mogę tego zmusić do działania, czy istnieje jakaś sztuczka? Czy moja metoda jest zasadniczo zła? Jak miałbym rysować koła do ImageView bez odtwarzania całego układu?

Dzięki!

Odpowiedz

0

Jeśli masz xml z układem ze wszystkimi elementami ułożonymi w pionową orientację.

Możesz osiągnąć to, co chcesz, tworząc klasę w pakiecie, która rozszerza widok klasy i zastępuje jego metodę onDraw. narysuj koło, jak chcesz.

wtedy zamiast dodawania ImageView w układzie dodaj swój własny pogląd w xml layout.like następujące

< LinearLayout>

< TextView> < /TextView> 

    < Button> < /Button> 

    <com.prac.MyView> </ com.prac.MyView> 

</LinearLayout>

Sprawdź poniższy link Grafika 2D. To świetny samouczek do przeczytania.
http://organicandroid.blogspot.com/2010/08/starting-to-play-with-graphics.html
Nadzieja ta pomoc:)

+0

Proszę zaktualizować link. Blog został usunięty –

0

Istnieje kilka sposobów na to, co chcesz, ale stosując ImageView sposób opisać nie jest jednym z nich. Jedną z możliwości jest wyświetlanie animowanego obrazu w trybie "Drawable". Następnie możesz skupić się na tym, aby implementacja Draw Draw narysowała kółka. Innym jest utworzenie nowej bitmapy za każdym razem, gdy chcesz zmienić obraz i ustawienie ImageView do wyświetlania nowej bitmapy. Jednak zwykłym sposobem jest stworzenie niestandardowej podklasy View. Przykładowy projekt API Demos ma przykład niestandardowego widoku i można znaleźć wiele tutoriali z Google.

26

Miałem takie samo wyzwanie i doszedłem do wniosku, że nadpisanie naDraw przynajmniej w ogólnym przypadku nie zadziała. My blog wyjaśnia powody. To, co sprawdziło się bardzo dobrze, to:

  1. Utwórz nową mapę bitową i dołącz do niej zupełnie nowe płótno.
  2. Narysuj bitmapę obrazu w obszarze roboczym.
  3. Narysuj wszystko, co chcesz, na płótnie.
  4. Dołącz płótno do ImageView.

Oto fragment kodu do tego:

import android.graphics.Bitmap; 
import android.graphics.Canvas; 
import android.graphics.Paint; 
import android.graphics.RectF; 
import android.graphics.drawable.BitmapDrawable; 

ImageView myImageView = ... 
Bitmap myBitmap = ... 
Paint myRectPaint = ... 
int x1 = ... 
int y1 = ... 
int x2 = ... 
int y2 = ... 

//Create a new image bitmap and attach a brand new canvas to it 
Bitmap tempBitmap = Bitmap.createBitmap(myBitmap.getWidth(), myBitmap.getHeight(), Bitmap.Config.RGB_565); 
Canvas tempCanvas = new Canvas(tempBitmap); 

//Draw the image bitmap into the cavas 
tempCanvas.drawBitmap(myBitmap, 0, 0, null); 

//Draw everything else you want into the canvas, in this example a rectangle with rounded edges 
tempCanvas.drawRoundRect(new RectF(x1,y1,x2,y2), 2, 2, myPaint); 

//Attach the canvas to the ImageView 
myImageView.setImageDrawable(new BitmapDrawable(getResources(), tempBitmap)); 
+0

Dzięki, działa dobrze – Lilo

+5

Tylko sugestia, ponieważ natknąłem się na ten sam problem, Zamiast tworzyć nową BitmapDrawable, Możemy również użyć funkcji myImageView.setImageBitmap (tempBitmap)! – balachandarkm

20
 ImageView imageView=(ImageView) findViewById(R.id.image); 
     Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);  
     Canvas canvas = new Canvas(bitmap); 
     Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); 
     paint.setColor(Color.BLACK); 
     canvas.drawCircle(50, 50, 10, paint); 
     imageView.setImageBitmap(bitmap); 
+0

i co jeśli chcę usunąć płótno po setImageBitmap? –

2

myślę, że lepszym rozwiązaniem byłoby stworzenie własnego ImageView i zastąpić metodę OnDraw.Coś jak:

public class CustomView extends ImageView { 

public CustomView(Context context) { 
    super(context); 
} 

public CustomView(Context context, AttributeSet attrst) { 
    super(context, attrst); 
} 

public CustomView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
} 

MyBitmapFactory bitMapFac = null; 
public void setBitmapFactory(MyBitmapFactory bitMapFac) 
{ 
    this.bitMapFac = bitMapFac; 
} 

@Override 
public void onDraw(Canvas canvas) { 

    canvas.drawColor(Color.TRANSPARENT); 
    /*instantiate a bitmap and draw stuff here, it could well be another 
    class which you systematically update via a different thread so that you can get a fresh updated 
    bitmap from, that you desire to be updated onto the custom ImageView. 
    That will happen everytime onDraw has received a call i.e. something like:*/ 
    Bitmap myBitmap = bitMapFac.update(); //where update returns the most up to date Bitmap 
    //here you set the rectangles in which you want to draw the bitmap and pass the bitmap   
    canvas.drawBitmap(myBitMap, new Rect(0,0,400,400), new Rect(0,0,240,135) , null); 
    super.onDraw(canvas); 
    //you need to call postInvalidate so that the system knows that it should redraw your custom ImageView 
    this.postInvalidate(); 
} 
} 

Byłoby to dobry pomysł, aby wdrożyć niektóre logiki, która sprawdza, czy jest świeże bitmapy do nabycia za pośrednictwem metody update(), tak, że kod wewnątrz OnDraw nie wykona za każdym razem i umieścić na górze systemu.

A następnie użyj niestandardowego widoku, gdziekolwiek go potrzebujesz. Najprostszym sposobem byłoby zadeklarować go bezpośrednio wewnątrz activity_layout.xml jako takie:

<com.mycustomviews.CustomView 
     android:id="@+id/customView" 
     android:layout_centerInParent="true" 
     android:layout_height="135dp" 
     android:layout_width="240dp" 
     android:background="@android:color/transparent"/> 

I wtedy dostęp jest w kodzie jak każdy inny widok za pomocą:

customView = (CustomView) findViewById(R.id.customView);