我正在呼叫invalidate()
,呼叫onDraw()
。运行doInBackGround()
后,我希望在屏幕上显示的位图未显示。有人可以帮忙吗?
这是我到目前为止测试过的。
当我放置相同的代码行时
canvas.drawBitmap();
onPreExecute()
中的可行,但在onPostExecute()
中,它不会显示预期结果。
这是我的代码:
public class FloorAppActivity extends Activity {
private Context globalContext;
private Point displaySize;
private int displayWidth;
private int displayHeight;
private String floorID;
private String floorName;
private String floorGridNumStr;
private int floorGridNum;
private String floorNumStr;
private int positionX;
private int positionY;
private int XCoord;
private int YCoord;
private int ZCoord;
private float signalStr;
private Integer dBm;
private Bitmap floorPlan;
private Bitmap userMark;
private Bitmap redPin;
private FloorView floorView;
private Connection conn = null;
private Canvas canvas=null;
private int newScrollRectX=0;
private int newScrollRectY=0;
private Paint paint;
private boolean a = false;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
globalContext = this;
floorID = getIntent().getStringExtra("floorID");
floorName = getIntent().getStringExtra("floorName");
positionX = getIntent().getIntExtra("userPositionX",-1);
positionY = getIntent().getIntExtra("userPositionY",-1);
dBm = getIntent().getIntExtra("BestSignal", -1);
//Get the grid number
if(Integer.parseInt(floorName.substring(floorName.lastIndexOf("_")+1))<10)
floorGridNumStr = floorName.substring(8, 9);
else
floorGridNumStr = floorName.substring(8, 10);
floorGridNum = Integer.parseInt(floorGridNumStr);
floorNumStr = floorName.substring(5,7);
Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
displaySize = new Point();
try {
// GetSize is not available in older models of Android
display.getSize(displaySize);
} catch (java.lang.NoSuchMethodError ignore) { // Older device
displaySize.x = display.getWidth();
displaySize.y = display.getHeight();
}
try {
InputStream source = getAssets().open(floorID);
floorPlan = BitmapFactory.decodeStream(source);
displayWidth = Math.min(displaySize.x, floorPlan.getWidth());
displayHeight = Math.min(displaySize.y, floorPlan.getHeight());
userMark = BitmapFactory.decodeResource(getResources(),R.drawable.star);
redPin = BitmapFactory.decodeResource(getResources(),R.drawable.redpin);
floorView = new FloorView(this);
setContentView(floorView);
}
catch (IOException e) {
MapServerAPI server = new MapServerAPI(globalContext,"Retrieving floor plan. Please wait...") {
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
if (bitmap == null)
Toast.makeText(globalContext, "Error in retrieving floor plan!", Toast.LENGTH_LONG).show();
else {
floorPlan = bitmap;
displayWidth = Math.min(displaySize.x, floorPlan.getWidth());
displayHeight = Math.min(displaySize.x, floorPlan.getHeight());
userMark = BitmapFactory.decodeResource(getResources(),R.drawable.star);
redPin = BitmapFactory.decodeResource(getResources(),R.drawable.redpin);
floorView = new FloorView(globalContext);
setContentView(floorView);
}
}
};
server.execute(floorID);
}
}
@Override
public void onResume() {
super.onResume();
registerReceiver(broadcastReceiver,new IntentFilter("FingerPrint_LOCATION_UPDATE"));
}
@Override
public void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
}
// listen for user location change
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String result = intent.getStringExtra("location");
Toast.makeText(context,result,Toast.LENGTH_LONG).show();
String floorId = intent.getStringExtra("floorID");
floorName = intent.getStringExtra("name");
dBm = intent.getIntExtra("BestSignal", -1);
int userLocationX = intent.getIntExtra("userPositionX",-1);
int userLocationY = intent.getIntExtra("userPositionY",-1);
//Get the grid number
if(Integer.parseInt(floorName.substring(floorName.lastIndexOf("_")+1))<10)
floorGridNumStr = floorName.substring(8, 9);
else
floorGridNumStr = floorName.substring(8, 10);
floorGridNum = Integer.parseInt(floorGridNumStr);
floorNumStr = floorName.substring(5,7);
if(!floorId.equals(floorID)){
positionX = userLocationX;
positionY = userLocationY;
InputStream source=null;
try {
source = getAssets().open(floorID);
} catch (IOException e) {
}
floorPlan = BitmapFactory.decodeStream(source);
floorView.postInvalidate();
}
}
};
private class FloorView extends View {
private Rect displayRect; //rect we display to
private Rect scrollRect; //rect we scroll over our bitmap with
private int scrollRectX = 0; //current left location of scroll rect
private int scrollRectY = 0; //current top location of scroll rect
private float scrollByX = 0; //x amount to scroll by
private float scrollByY = 0; //y amount to scroll by
private float startX = 0; //track x from one ACTION_MOVE to the next
private float startY = 0; //track y from one ACTION_MOVE to the next
public FloorView(Context context) {
super(context);
// Destination rect for our main canvas draw. It never changes.
displayRect = new Rect(0, 0, displayWidth, displayHeight);
// Scroll rect: this will be used to 'scroll around' over the
// bitmap in memory.
if (positionX + displayWidth / 2 > floorPlan.getWidth())
scrollRectX = floorPlan.getWidth() - displayWidth;
else
scrollRectX = positionX - displayWidth / 2;
if (scrollRectX < 0)
scrollRectX = 0;
if (positionY + displayHeight / 2 > floorPlan.getHeight())
scrollRectY = floorPlan.getHeight() - displayHeight;
else
scrollRectY = positionY - displayHeight / 2;
if (scrollRectY < 0)
scrollRectY = 0;
scrollRect = new Rect(scrollRectX, scrollRectY, displayWidth, displayHeight);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// Remember our initial down event location.
startX = event.getRawX();
startY = event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
float x = event.getRawX();
float y = event.getRawY();
// Calculate move update. This will happen many times
// during the course of a single movement gesture.
scrollByX = x - startX; //move update x increment
scrollByY = y - startY; //move update y increment
startX = x; //reset initial values to latest
startY = y;
invalidate(); //force a redraw
break;
}
return true; //done with this event so consume it
}
@Override
protected void onDraw(Canvas canvas1) {
canvas=canvas1;
// Our move updates are calculated in ACTION_MOVE in the opposite direction
// from how we want to move the scroll rect. Think of this as dragging to
// the left being the same as sliding the scroll rect to the right.
newScrollRectX = scrollRectX - (int)scrollByX;
newScrollRectY = scrollRectY - (int)scrollByY;
// Don't scroll off the left or right edges of the bitmap.
if (newScrollRectX < 0)
newScrollRectX = 0;
else if (newScrollRectX > (floorPlan.getWidth() - displayWidth))
newScrollRectX = (floorPlan.getWidth() - displayWidth);
// Don't scroll off the top or bottom edges of the bitmap.
if (newScrollRectY < 0)
newScrollRectY = 0;
else if (newScrollRectY > (floorPlan.getHeight() - displayHeight))
newScrollRectY = (floorPlan.getHeight() - displayHeight);
// We have our updated scroll rect coordinates, set them and draw.
scrollRect.set(newScrollRectX, newScrollRectY,
newScrollRectX + displayWidth, newScrollRectY + displayHeight);
paint = new Paint();
canvas.drawBitmap(floorPlan, scrollRect, displayRect, paint);
// Update user position
if (positionX >= newScrollRectX && positionX - newScrollRectX <= displayWidth
&& positionY >= newScrollRectY && positionY - newScrollRectY <= displayHeight)
canvas.drawBitmap(userMark,positionX-newScrollRectX-userMark.getWidth()/2,positionY-newScrollRectY-userMark.getHeight()/2,paint);
class AsyncTaskToConnect extends AsyncTask <Void, Void, Void>{
@Override
protected Void doInBackground(Void... cmd) {
// connect to database and retrieve values
return null;
}
@Override
protected void onPostExecute(Void v)
{//PE
if (positionX >= newScrollRectX && positionX - newScrollRectX <= displayWidth
&& positionY >= newScrollRectY && positionY - newScrollRectY <= displayHeight)
{
canvas.drawBitmap(redPin,480-newScrollRectX-userMark.getWidth()/2,90-newScrollRectY-userMark.getHeight()/2,paint);
}
//return null;
// Reset current scroll coordinates to reflect the latest updates,
// so we can repeat this update process.
scrollRectX = newScrollRectX;
scrollRectY = newScrollRectY;
}//PE
}
AsyncTaskToConnect[] asyncTaskC = null;
asyncTaskC = new AsyncTaskToConnect[1];
asyncTaskC[0] = new AsyncTaskToConnect();
asyncTaskC[0].executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
// Cache our new dimensions; we'll need them for drawing.
displayWidth = Math.min(w, floorPlan.getWidth());
displayHeight = Math.min(h, floorPlan.getHeight());
// Destination rect for our main canvas draw.
displayRect = new Rect(0, 0, displayWidth, displayHeight);
// Scroll rect: this will be used to 'scroll around' over the
// bitmap in memory.
if (positionX + displayWidth / 2 > floorPlan.getWidth())
scrollRectX = floorPlan.getWidth() - displayWidth;
else
scrollRectX = positionX - displayWidth / 2;
if (scrollRectX < 0)
scrollRectX = 0;
if (positionY + displayHeight / 2 > floorPlan.getHeight())
scrollRectY = floorPlan.getHeight() - displayHeight;
else
scrollRectY = positionY - displayHeight / 2;
if (scrollRectY < 0)
scrollRectY = 0;
scrollRect = new Rect(scrollRectX, scrollRectY, displayWidth, displayHeight);
super.onSizeChanged(w, h, oldw, oldh);
}
}
}
P.S。这是我第一次发帖。如果我在帖子中犯了错误,请原谅我。感谢。
答案 0 :(得分:0)
我认为问题在于您存储了传递到Canvas
方法的onDraw
对象。 onDraw
方法返回后,该对象可能无效。
看起来您正在尝试在后台线程上准备Bitmap
,然后在准备好时在屏幕上绘制它。您这样做的方法是 - 准备Bitmap
,然后只需invalidate
方法View
上的onPostExecute
。然后在onDraw
方法中,您可以使用Bitmap
对象并使用canvas.drawBitmap