Eigene View in separatem Thread zeichnen

  • Antworten:0
Wicki12
  • Forum-Beiträge: 38

28.08.2012, 13:52:34 via Website

Hallo,

ich habe eine eigene View, die ich in einem separaten Thread zeichnen lassen will. Für die Nutzung des Threads verwende ich eine von AsyncTask abgeleitete Klasse. Das Bild der View soll einen Hintergrund (z.B. eine bestimmte Farbe) und eine darauf gezeichnete Bitmap enthalten, die ich in Form eines png-Bildes im res/drawable-Verzeichnis bereitstelle. Es gelingt mir nicht, diese Darstellung in der onDraw-Methode meiner View zu erzeugen.
Hier der Code:
1<!-- main.xml -->
2<?xml version="1.0" encoding="utf-8"?>
3<FrameLayout
4 xmlns:android="http://schemas.android.com/apk/res/android"
5 android:orientation="vertical"
6 android:id="@+id/framelayout0"
7 android:background="#0000ff"
8 android:layout_width="fill_parent"
9 android:layout_height="fill_parent">
10</FrameLayout>
11
12public class UFOActivity extends Activity {
13 private UFOView ufoView;
14
15 @Override
16 public void onCreate(Bundle savedInstanceState) {
17 super.onCreate(savedInstanceState);
18 setContentView(R.layout.main);
19
20 // UI vervollständigen
21 ufoView = new UFOView(this);
22
23 FrameLayout fl = (FrameLayout) findViewById(R.id.framelayout0);
24 fl.addView(ufoView);
25 }
26}
27
28public class UFOView extends View {
29 private float xpos = -1;
30 private float ypos = -1;
31 private Bitmap ufoBitmap;
32 private int touchX;
33 private int touchY;
34 Canvas cvm;
35 boolean async=true;
36 boolean invalid=false;
37
38 public UFOView(Context c) {
39 super(c);
40 // lade Hintergrund
41 //this.setBackgroundResource(R.drawable.hintergrund);
42 // lade Bitmap für UFO
43 Resources resources = getResources();
44 ufoBitmap = BitmapFactory.decodeResource(resources, R.drawable.ufo); //zum Test png-Bild nehmen
45 setFocusable(true);
46 if (async) new MyAsyncTask().execute(cvm);
47 }
48
49 @Override
50 protected void onDraw(Canvas canvas) {
51 super.onDraw(canvas);
52 if (async) { //**** Variante mit Zeichnen in separatem Thread (MyAsyncTask)
53/* ************ dieser Teil funktionierte leider nicht
54 if (invalid) { //Aufruf onDraw indirekt von 'onPostExecute'
55 canvas=cvm; //die dort erstellte Canvas
56 invalid=false;
57 return;
58 }
59*/
60 cvm=canvas;
61 //bewirkt Aufruf Methode 'doInBackground', Abarbeitung in separatem Thread
62 new MyAsyncTask().execute(cvm);
63 } else { //**** Variante ohne Zeichnen in separatem Thread
64 // Startposition getWidth() funktioniert nicht in onCreate() oder
65 // onStart()
66 if (xpos == -1 && ypos == -1) {
67 xpos = getWidth() / 2;
68 ypos = getHeight() / 2;
69 }
70
71 // UFO-Bitmap einzeichnen
72 Paint iconPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
73
74 if (ufoBitmap != null) {
75 canvas.drawBitmap(ufoBitmap, xpos - ufoBitmap.getWidth() / 2, ypos
76 - ufoBitmap.getHeight() / 2, iconPaint);
77 }
78 }
79 }
80
81 @Override
82 public boolean onKeyDown(int keyCode, KeyEvent event) {
83 if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
84 ypos -= 5;
85 }
86 if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
87 xpos += 5;
88 }
89 if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
90 ypos += 5;
91 }
92 if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
93 xpos -= 5;
94 }
95 if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
96 xpos = getWidth() / 2;
97 ypos = getHeight() / 2;
98 }
99 if (async)
100 new MyAsyncTask().execute(cvm);
101 else
102 invalidate();
103 return super.onKeyDown(keyCode, event);
104 }
105
106 @Override
107 public boolean onTouchEvent(MotionEvent event) {
108 int aktion = event.getAction();
109
110 if(aktion == MotionEvent.ACTION_DOWN) {
111 touchX = (int) event.getX();
112 touchY = (int) event.getY();
113 }
114 if(aktion == MotionEvent.ACTION_UP) {
115 int tx = (int) event.getX();
116 int ty = (int) event.getY();
117 if( (touchX - tx) > 20) {
118 xpos -= 25;
119 } else if ((touchX - tx) <= -20){
120 xpos += 25;
121 }
122 if( (touchY - ty) > 20) {
123 ypos -= 25;
124 } else if( (touchY - ty) <= -20) {
125 ypos += 25;
126 }
127 }
128 if (async)
129 new MyAsyncTask().execute(cvm);
130 else
131 invalidate();
132 return true; // super.onTouchEvent(event);
133 }
134
135/*
136 * To use AsyncTask you must subclass it. AsyncTask uses generics and varargs.
137 * The parameters are the following:
138 * AsyncTask <TypeOfVarArgParams , ProgressValue , ResultValue> .
139 * TypeOfVarArgParams is passed into the doInBackground() method as input,
140 * ProgressValue is used for progress information and
141 * ResultValue must be returned from doInBackground() method and is passed to onPostExecute() as parameter.
142 */
143 private class MyAsyncTask extends AsyncTask<Canvas,Void,Canvas> {
144 protected Canvas doInBackground(Canvas... c) {
145 Canvas cv;
146 if (c[0] != null)
147 cv=c[0];
148 else
149 cv = new Canvas();
150 if (xpos == -1 && ypos == -1) {
151 xpos = getWidth() / 2;
152 ypos = getHeight() / 2;
153 }
154 // UFO-Bitmap einzeichnen
155 Paint iconPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
156
157 if (ufoBitmap != null) {
158 cv.drawBitmap(ufoBitmap, xpos - ufoBitmap.getWidth() / 2, ypos
159 - ufoBitmap.getHeight() / 2, iconPaint);
160 }
161 return cv;
162 }
163 protected void onPostExecute(Canvas cv) {
164 cvm = cv;
165 invalid=true;
166 invalidate();
167 }
168 }
169}

Hat jemand eine Idee, wie ich das Problem lösen kann ?

Gruß Wicki

Antworten