android2014.06.26 09:39
31 May
3

Fading ActionBar

FadingActionBar is a library which implements the cool fading action bar effect that can be seen in the new Play Music app.

This library uses the techniques outlined by Cyril Mottier in a recent blog post.

For reasons of backwards compatibility this library relies on ActionBarSherlock. If your app uses the native action bar, there is a fork for you.

Download from GitHub

https://github.com/ManuelPeinado/FadingActionBar

신고
Posted by 레드오이
android2012.10.12 10:23

public boolean onTouchEvent(MotionEvent event) {


toViewRawXY(list_slide);

// 현재의 터치 액션의 종류를 받아온다.

int action = event.getAction();

// 터치 된 x좌표

float x = event.getX();

// 터치 된 y좌표

float y = event.getY();

// 액션의 종류에 따른 역할 수행


Log.d("=-=-=-=-=-", "=-=-=a=-=-a=-a=-a=-a=-a=-" + event.getX());

Log.d("=-=-=-=-=-", "=-=-=a=-=-a=-a=-a=-a=-a=-" + event.getY());

Log.d("1111111111", "x좌표왼쪽::" + list_slide.getLeft());

Log.d("1111111111", "x좌표오른쪽::" + list_slide.getRight());

Log.d("1111111111", "y좌표왼쪽::" + list_slide.getTop());

Log.d("1111111111", "y좌표오른쪽::" + list_slide.getBottom());

switch (action) {

// 드래그 되었을 때의 이벤트 처리

case MotionEvent.ACTION_DOWN:

// 터치 좌표가 이미지 안에 들어와 있다면 드래그 된 만큼 이미지의 좌표도 이동시킨다.

if (x > list_slide.getLeft() && x < list_slide.getRight()

&& y > list_slide.getTop() && y < list_slide.getBottom()) {

Log.d("=-=-=-=-=-", "=-=-=a=-=-a=-a=-a=-a=-a=-");

}

break;

}

return true;

};

신고
Posted by 레드오이
android2012.10.11 21:07

private ProgressDialog pd;


void createThreadAndDialog() {//다이알로그 실행함수 쓰레드도 돌고 

pd = ProgressDialog.show(this, getResources().getText(R.string.hello),

getResources().getText(R.string.hello), true, false);

pd.setCancelable(true);

Thread thread = new Thread(new Runnable() {

public void run() {


boolean connettResult = isOnline();

if (connettResult) {

// 페이지접속이 됬는지 true값

// Message msg = handler.obtainMessage();

// handler.sendMessage(msg);


handler.sendMessage(Message.obtain(handler, 1));

} else {

// 페이지접속이 됬는지 false값

// connectAlert();

// pd.dismiss();


handler.sendMessage(Message.obtain(handler, 2));

}

}

});

thread.start();

}


private Handler handler = new Handler() {

public void handleMessage(Message msg) {


switch (msg.what) { // 메시지 처리

case 1:

pd.dismiss();

connectComplete(); // 나는 함수를 호출하였다.

break;

case 2: // 기타 전달인자로 인한 처리도 가능

connectAlert();

pd.dismiss();

break;

case 3:

break;

}

// pd.dismiss();

// connectComplete();


}


};


private void connectAlert() {

AlertDialog.Builder alert = new AlertDialog.Builder(this);


// 제목, 메시지, icon, 버튼

alert.setTitle("경고");

alert.setMessage("접속불가");

alert.setIcon(R.drawable.bus_icon);


// cancel : false = 단말기 back button으로 취소되지 않음.

alert.setCancelable(false);


// yes

alert.setPositiveButton("뒤로가기", new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog, int id) {

dialog.dismiss(); // dialog 사라짐

onBackPressed();

}

});


// no

alert.setNegativeButton("재접속", new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog, int id) {

dialog.cancel();

createThreadAndDialog();

}

});


alert.show();

}


public boolean isOnline() {

ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

NetworkInfo netInfo = cm.getActiveNetworkInfo();

if (netInfo != null && netInfo.isConnected()) {

try {

URL url = new URL(onlineURL);

Log.d("=======", "-----" + onlineURL);

HttpURLConnection urlc = (HttpURLConnection) url

.openConnection();

urlc.setConnectTimeout(3000);

urlc.connect();

int aaa = urlc.getResponseCode();

int bbb = 200;

if (aaa == bbb) {

// 200코드=접속확인코드번호 404코드는 접속에러

return new Boolean(true);

}

} catch (MalformedURLException e1) {

// TODO Auto-generated catch block

e1.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

return false;

}


public void connectComplete() {// 완료 함수 

Log.d("====", onlineURL + RM_IDX + "&rt_start=" + RT_START);

connectJson(onlineURL + RM_IDX + "&rt_start=" + RT_START);


}




///////////


private String connectJson(String url) {

// Create the httpclient

HttpClient httpclient = new DefaultHttpClient();


// Prepare a request object

HttpGet httpget = new HttpGet(url);


// Execute the request

HttpResponse response;


// return string

String returnString = null;


try {


// Open the webpage.

response = httpclient.execute(httpget);


if (response.getStatusLine().getStatusCode() == 200) {

// Connection was established. Get the content.


HttpEntity entity = response.getEntity();

// If the response does not enclose an entity, there is no need

// to worry about connection release


if (entity != null) {

// A Simple JSON Response Read

InputStream instream = entity.getContent();

Log.d("=======", "========" + "나오나1나오나1" + instream);


// Load the requested page converted to a string into a

// JSONObject.

String result = "";

Log.d("=======", "========" + "나오나3" + instream);

ja1 = new JSONArray(convertStreamToString(instream));

Log.d("=======", "========" + "나오나4" + instream);


JSONObject order = ja1.getJSONObject(0);

NAME_LIST = order.getString("NAME_LIST").split("\\,");

LAT_LIST = order.getString("LAT_LIST").split("\\,");

LONG_LIST = order.getString("LONG_LIST").split("\\,");

Log.d("###", NAME_LIST + " | " + NAME_LIST.length);

// final String[] array_RM_NAME = new

// String[NAME_LIST.length];

// final String[] array_LAT_LIST = new

// String[LAT_LIST.length];

// final String[] array_LONG_LIST = new

// String[LONG_LIST.length];

float dism = 600000;


for (int i = 0; i < NAME_LIST.length; i++) {

List<String> filelist_name = Arrays.asList(NAME_LIST);

ar_name = new ArrayList<String>(filelist_name);


List<String> filelist_lat = Arrays.asList(LAT_LIST);

ar_lat = new ArrayList<String>(filelist_lat);


List<String> filelist_long = Arrays.asList(LONG_LIST);

ar_long = new ArrayList<String>(filelist_long);


Log.d("###", NAME_LIST[i] + " | " + LAT_LIST[i] + " | "

+ LONG_LIST[i] + filelist_name);


// ar_lat = ar_lat[i];

// LAT_value = LAT_LIST[i];


if (LONG_LIST.length > 0 && LAT_LIST.length > 0) {

// busLocal = [[CLLocation alloc]

// initWithLatitude:[latCK doubleValue]

// longitude:[longCK doubleValue]];

//

//

// CLLocationDistance dis = [nowS1

// distanceFromLocation:busLocal];


Location locationA = new Location("point A");


locationA.setLatitude(Double

.parseDouble(LAT_LIST[i]));

locationA.setLongitude(Double

.parseDouble(LONG_LIST[i]));


Location locationB = new Location("point B");


locationB.setLatitude(37.5604);

locationB.setLongitude(126.9739);


float distance = locationA.distanceTo(locationB);


Log.d("==========", distance + "||");


if (dism > (float) distance) {

dism = (float) distance;

nowthin = i;

Log.d("==========", i + "||");

}

}


HashMap<String, String> jsonMap = new HashMap<String, String>();

jsonMap.put("NAME_LIST", NAME_LIST[i]);

jsonMap.put("LAT_LIST", LAT_LIST[i]);

jsonMap.put("LONG_LIST", LONG_LIST[i]);

Log.d("=======", "========" + nowthin);

listSEARCH.add(jsonMap);

}


System.out.println("json - " + result);

search(nowthin);

instream.close();

}

} else {

returnString = "Unable to load page - "

+ response.getStatusLine();

}

} catch (IOException ex) {

// thrown by line 80 - getContent();

// Connection was not established

returnString = "Connection failed; " + ex.getMessage();

} catch (JSONException ex) {

// JSON errors

returnString = "JSON failed; " + ex.getMessage();

}

return returnString;

}


private static String convertStreamToString(InputStream is) {

BufferedReader reader = new BufferedReader(new InputStreamReader(is));

StringBuilder sb = new StringBuilder();


String line = null;

try {

while ((line = reader.readLine()) != null) {

sb.append(line + "\n");

}

} catch (IOException e) {

e.printStackTrace();

} finally {

try {

is.close();

} catch (IOException e) {

e.printStackTrace();

}

}

return sb.toString();

}

신고
Posted by 레드오이
android2012.10.11 21:01

[Soft Keyboard 가 뭔가요?]

접기

일반 Keyboard 처럼 기계적으로 직접 키를 누르는 것이 아니라, 터치 스크린 등의 가상의 키보드를 통해 입력하는 것을 Soft Input 이라고 하며, 이 때 사용되는 가상의 키보드는 Soft Keyboard 라고 합니다.

접기




어떤 값들이 들어갈 수 있나요?


android:windowSoftInputMode = "state mode | adjust mode " 의 형태로 주로 사용합니다.

예를 한번 볼까요?

<activity android:windowSoftInputMode="stateVisible|adjustResize" . . . >



state mode 는 말 그대로, 보여줄 지 안 보여줄지에 대한 mode 설정.
adjust mode 는 말 그대로, soft keyboard 가 나올 때 화면을 어떻게 조정할 것인지에 대한 mode 설정 입니다.

이 때 주의할 것은 state mode 또는 adjust mode 또는 state mode | adjust mode 는 가능하지만,
이 외의 경우에 대해서는 undefined 값으로 바뀌어 설정됩니다. 이 점을 주의하셔야 하겠습니다.

 Value Description
 stateUnspecified설정값 없음 ( undefined ). System에서 알아서 적절히 설정하거나 Theme에 영향을 받는다. 
 stateUnchanged지난 setting 값을 유지한다. 
 stateHiddenactivity "진입" 시에 keyboard 를 숨긴다. ( resume으로 돌아오는 경우는 적용되지 않는다. ) 
 stateVisibleactivity "진입" 시에 특이 사항이 없다면 keyboard 를 보여준다. 
 stateAlwaysVisibleactivity "진입" 시에 항상 keyboard 를 보여준다. 
( resume으로 돌아오는 경우는 적용되지 않는다. ) 
 adjustUnspecified설정값 없음( undefined ). System에서 알아서 mode 설정. 
여기서 System 설정은 Scroll 가능한 View 를 가지고 있다면 Resize 함.
 adjustResize Soft keyboard 공간을 위해 activity 를 resize 한다.
 adjustPanWindow의 focus를 input focus에 위치하도록 이동하여 보여준다. 
Typing 하는 동안에는 해당 view 를 볼 수 있지만, 
다른 UI 의 시야를 방해할 수 있기 때문에 추천되지는 않는다.


[adjustResize 와 adjustPan에 대한 상세 설명]

접기

화면의 최하단에 EditText가 있다고 가정하고, EditText를 Click 하여 Soft Keyboard를 띄웠을 때 다음과 같은 차이가 있습니다.

1. adjustResize 는 메인 윈도우의 사이즈가 줄어듭니다. Focus를 받은 EditText 가 보이지 않을 수 있습니다. ( 최하단에 있기 때문에 그럴 가능성이 매우 큽니다. ) Activity 에서 Scroll 이 지원된다면 Scroll 하여 해당 View 를 볼 수 있습니다.

2. adjustPan 은 메인윈도우의 사이즈는 그대로 유지되고, Focus를 받은 EditText가 보이도록 화면의 focus가 이동됩니다. EditText 자체는 보이나, 위쪽에 존재하는 다른 UI 들은 보이지 않습니다. 

접기


신고
Posted by 레드오이
android2012.10.11 20:39

[출처]

http://developer.android.com/reference/android/widget/TextView.html#attr_android:imeOptions


여러분의 응용 프로그램과 통합을 개선하기 위해 에디터와 관련된 입력기에 설정할 수 있는 

추가 기능. 상수는 아래의 imeOptions에 의해 정의된 것과 일치합니다.

아래의 상수값들 중 하나가 되어야하고 하나 이상일때는 '|' 로 구분해야 합니다.

<!-- 이 에디터와 관련된 특별한 의미가 없습니다. -->

<EditText

...

android:imeOptions="normal"

/>


<!-- 이 에디터와 관련된 특별한 Action이 없습니다.

에디터가 할수 있다면 스스로 생기게 합니다.

EditorInfo.IME_NULL 과 일치합니다. --> 

<EditText

...

android:imeOptions="actionUnspecified"

/>


<!-- 이 에디터는 에디터와 관련된 Action을 가지고 있지 않습니다. EditorInfo.IME_ACTION_NONE 과 일치합니다. -->

<EditText

...

android:imeOptions="actionNone"

/>


<!-- Action key가 사용자가 입력한 텍스트의 target으로 사용자를 데려가는 "이동" 작업을 수행합니다. 일반적으로 예를 들면 URL을 입력할 때 사용합니다. EditorInfo.IME_ACTION_GO 와 일치합니다. -->

<EditText

...

android:imeOptions="actionGo"

/>

 


<!-- Action key가 (문맥이 적절한지에 상관없이) 입력한 텍스트 검색 결과로 사용자를 데려가는 "검색" 작업을 수행합니다. EditorInfo.IME_ACTION_SEARCH 와 일치합니다. -->

<EditText

...

android:imeOptions="actionSearch"

/>

 


<!-- Action key가 target으로 텍스트를 제공하는 "보내기" 작업을 수행합니다. 이것은 일반적으로 메시지를 작성할 때 사용됩니다. EditorInfo.IME_ACTION_SEND 와 일치합니다. -->

<EditText

...

android:imeOptions="actionSend"

/>

 


<!-- Action key가 텍스트를 받아들이는 다음 필드로 사용자를 데려가는 "다음" 작업을 수행합니다.  EditorInfo.IME_ACTION_NEXT 와 일치합니다. -->

<EditText

...

android:imeOptions="actionNext"

/>


<EditText

...

/>

 


<!-- Action key가 soft input method를 닫는 "완료" 작업을 수행합니다. EditorInfo.IME_ACTION_DONE 과 일치합니다. -->

<EditText

...

android:imeOptions="actionDone"

/>

 


<!-- Action key가 텍스트를 받아들이는 이전 필드로 사용자를 데려가는 "이전" 작업을 수행합니다. EditorInfo.IME_ACTION_PREVIOUS 와 일치합니다.  -->

<EditText

...

android:imeOptions="actionPrevious"

/>

 API Level 11 이상부터 사용할 수 있습니다.


<!-- Used to specify that the IME does not need to show its extracted text UI. For input methods that may be fullscreen, often when in landscape mode, this allows them to be smaller and let part of the application be shown behind. Though there will likely be limited access to the application available from the user, it can make the experience of a (mostly) fullscreen IME less jarring. Note that when this flag is specified the IME may not be set up to be able to display text, so it should only be used in situations where this is not needed.

EditorInfo.IME_FLAG_NO_EXTRACT_UI 와 일치합니다. -->

<EditText

...

android:imeOptions="flagNoExtractUi"

/>

 


<!-- Used in conjunction with a custom action, this indicates that the action should not be available as an accessory button when the input method is full-screen. Note that by setting this flag, there can be cases where the action is simply never available to the user. Setting this generally means that you think showing text being edited is more important than the action you have supplied.

EditorInfo.IME_FLAG_NO_ACCESSORY_ACTION 과 일치합니다. -->

<EditText

...

android:imeOptions="flagNoAccessoryAction"

/>

 


<!-- Used in conjunction with a custom action, this indicates that the action should not be available in-line as a replacement for the "enter" key. Typically this is because the action has such a significant impact or is not recoverable enough that accidentally hitting it should be avoided, such as sending a message. Note that TextView will automatically set this flag for you on multi-line text views.

EditorInfo.IME_FLAG_NO_ENTER_ACTION 과 일치합니다. -->

<EditText

...

android:imeOptions="flagNoEnterAction"

/>

 


<!-- 전체 화면 모드로 절대로 가지 않는 입력기를 요청하기 위해 사용. Applications need to be aware that the flag is not a guarantee, and not all IMEs will respect it.

EditorInfo.IME_FLAG_NO_FULLSCREEN 과 일치합니다. -->

<EditText

...

android:imeOptions="flagNoFullscreen"

/>

 API Level 11 이상부터 사용할 수 있습니다.


<!-- Like flagNavigateNext, but specifies there is something interesting that a backward navigation can focus on. If the user selects the IME's facility to backward navigate, this will show up in the application as an actionPrevious at InputConnection.performEditorAction(int).

EditorInfo.IME_FLAG_NO_FULLSCREEN 과 일치합니다. -->

<EditText

...

android:imeOptions="flagNavigatePrevious"

/>

 API Level 11 이상부터 사용할 수 있습니다.


<!-- Used to specify that there is something interesting that a forward navigation can focus on. This is like using actionNext, except allows the IME to be multiline (with an enter key) as well as provide forward navigation. Note that some IMEs may not be able to do this, especially when running on a small screen where there is little space. In that case it does not need to present a UI for this option. Like actionNext, if the user selects the IME's facility to forward navigate, this will show up in the application atInputConnection.performEditorAction(int).

EditorInfo.IME_FLAG_NAVIGATE_NEXT 와 일치합니다. -->

<EditText

...

android:imeOptions="flagNavigateNext"

/>

 API Level 11 이상부터 사용할 수 있습니다.


신고
Posted by 레드오이
android2012.10.11 20:37

MapView 상의 지도에 텍스트, 이미지, 도형 등을 출력하려면 Overlay 클래스를 상속하여 draw()를 오버라이드할 때 Canvas에 이미지(Bitmap클래스의 인스턴스)를 그리도록 작성하면 된다. 여기서는 지도상의 특정 위치를 가리키는 적색 화살표를 지도위에 그려본다.

이미지는 JPEG, GIF, PNG등을 사용하면 되고 프로젝트의 drawable 폴더에 import해 두면 R.java 파일에 자동으로 등록되어 Activity클래스의 onCreate() 안에서 쉽게 로드할 수 있다.

사용된 화살표 이미지

(arrow.png)

MyOverlay.java

앞글의 내용과 동일하며 다른 부분은 적색으로 표시했다.

package com.ojtit.android.demo;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;

public class MyOverlay extends Overlay {
 
 private Bitmap arrow;
 
 public MyOverlay(Bitmap bitmap){
  this.arrow = bitmap;
 }

 
 @Override
 public void draw(Canvas canvas, MapView mapView, boolean shadow) {
 
  super.draw(canvas, mapView, shadow);
        
     Paint paint1 = new Paint();
     Paint paint2 = new Paint();

     paint1.setARGB(255, 255, 0, 0); // a, r, g, b
     paint2.setARGB(255, 255, 0,0);

     // 아래에서 사용된 아규먼트는 위도, 경도 정보(40.756054)에서 가운데 '.' 을 뺀 것
     GeoPoint geoPoint = new GeoPoint(37517180,127041268); 
      
     Point pixPoint = new Point(); 
      
     mapView.getProjection().toPixels(geoPoint, pixPoint); // 지리적 위치를 화면상의 픽셀위치로 변환

     // drawCircle(float cx, float cy, float radius, Paint paint) ;
     // drawLine(float startX, float startY, float stopX, float stopY, Paint paint) ;
     // drawText(String text, float x, float y, Paint paint) ;
     //canvas.drawCircle(pixPoint.x, pixPoint.y, 10, paint1);
     //drawBitmap(Bitmap bitmap, float left, float top, Paint paint);

        
     canvas.drawBitmap(arrow, pixPoint.x-11, pixPoint.y, paint2);
     canvas.drawText("강남구청역", pixPoint.x-30, pixPoint.y + 30, paint2);    
 }
 
}


GoogleMapsActivity.java
앞글의 내용과 거의 동일하지만, 리소스로부터 화살표 이미지를 읽어서 Bitmap 인스턴스로 리턴하고 다시 MyOverlay 클래스의 생성자로 전달하여 Canvas에 화살표 이미지가 그려질 수 있도록 설정해준다

package com.ojtit.android.demo;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;

public class GoogleMapsActivity extends MapActivity
{

 @Override
 public void onCreate(Bundle savedInstanceState) 
 {
  super.onCreate(savedInstanceState); 
  setContentView(R.layout.main);
  MapView mapView = (MapView) findViewById(R.id.mapview);
  mapView.setBuiltInZoomControls(true); //지도 확대/축소기능 활성화
  
  // 리소스에서 arrow.png 를 가져와서 Bitmap 인스턴스를 생성한다
  Bitmap arrow = BitmapFactory.decodeResource(this.getResources(), R.drawable.arrow);


  //아래 라인을 사용하면 지도처럼 표현하는 것이 아니라 위성에서 촬영한 항공사진이 출력됨
  //mapView.setSatellite(true);

  
  //아래의 위도, 경도 좌표는 '37.517180' 에서 숫자 사이의 '.' 을 제거한 표현임
  GeoPoint geoPoint = new GeoPoint(37517180,127041268); // 강남구청역
  MapController mc = mapView.getController();
  mc.animateTo(geoPoint);
  mc.setZoom(17);
  
  // MapView 상의 지도 위에 표현할 것들을 그린다
  mapView.getOverlays().add(new MyOverlay(arrow));
 }
 
 @Override
 protected boolean isRouteDisplayed() {
  return true;
 }
}


Run As > Android Application

신고
Posted by 레드오이
android2012.10.11 20:34

* 현재 위치를 지도에 표시하기
1. 레이아웃 - my_map_view.xml 그대로 사용
2. 액티비티 - MyLocMap extends MapActivity implements LocationListener
:onCreate()에서 지도 초기화
1) 멤버변수 선언
LocationManager locationMgr = null;
MapController mapControl;
2) onCreate
setContentView(R.layout.my_map_view);
final MapView map = (MapView) findViewById(R.id.map);
mapControl = map.getController();

3. MyLocMap 액티비티가 실행되면 현재 위치 정보 가져오기
: onCreate()에서 현재 위치정보를 가져기 위한 requestLocationUpdates()함수 호출
locationMgr = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.NO_REQUIREMENT);
criteria.setPowerRequirement(Criteria.NO_REQUIREMENT);
String best = locationMgr.getBestProvider(criteria, true);
locationMgr.requestLocationUpdates(best, 1000, 0, MyLocationView.this);

4. 현재위치 정보 표시하기
: onLocationChanged()에서 GeoPoint 설정
double lat = location.getLatitude();
double lon = location.getLongitude();
GeoPoint newPoint = new GeoPoint((int)(lat * 1E6), (int)(lon*1E6));
mapControl.animateTo(newPoint);
mapControl.setZoom(15);
// 마커표시
MapView.LayoutParams mapMarkerParams = new MapView.LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT, newPoint,
MapView.LayoutParams.TOP_LEFT);
ImageView mapMarker = new ImageView(
getApplicationContext());
mapMarker.setImageResource(R.drawable.gmarker);
map.addView(mapMarker, mapMarkerParams);

///MyLocMap 액티비티 소스
package kcdi.map;

import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;

public class MyLocMap extends MapActivity implements LocationListener {
MapController mapControl;
MapView map;
LocationManager locationMgr = null;
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.my_map_view);
map = (MapView) findViewById(R.id.map);
mapControl = map.getController();
locationMgr = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.NO_REQUIREMENT);
criteria.setPowerRequirement(Criteria.NO_REQUIREMENT);
String best = locationMgr.getBestProvider(criteria, true);
locationMgr.requestLocationUpdates(best, 1000, 0, MyLocMap.this);
}
@Override
public void onLocationChanged(Location location) {
double lat = location.getLatitude();
double lon = location.getLongitude();
GeoPoint newPoint = new GeoPoint((int)(lat * 1E6), (int)(lon*1E6));
mapControl.animateTo(newPoint);
mapControl.setZoom(15);
MapView.LayoutParams mapMarkerParams = new MapView.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, newPoint,
MapView.LayoutParams.TOP_LEFT);
ImageView mapMarker = new ImageView(getApplicationContext());
mapMarker.setImageResource(R.drawable.gmarker);
map.addView(mapMarker, mapMarkerParams);
}

@Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
@Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub

}

@Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub

}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub

}

}

신고
Posted by 레드오이
android2012.10.11 20:32

[android] getTextBounds drawText

화면에 그릴 텍스트의 사이즈를 알아내기 위해
getTextBounds 함수를 사용하게 되는데,

이때 영어일경우엔 상관이 없었지만 한글이나 특수문자의 경우
영역이 내가 생각한대로 맞질않아서 계속 고생을 하였다.
몇번에 삽질끝에 알아낸 결과 getTextBounds 함수값에 그 해답이 있었다.

간단한 예제를 보자면


String text = "ABCD 1234";
Rect rt = new Rect();
ptText.getTextBounds(text, 0, text.length(), rt);
canvas.drawRect(rt, ptRound);
canvas.drawText(text, rt.left, rt.bottom, ptText);

 



위와같을경우 아무것도 출력되지않는다는걸 누구나 알수있다
getTextBounds로 구한 영역이 0,0을 기준으로 위에 있기때문이다



그러면 좌표를 조금 수정해서 다시 실행하여 보자.


int nX = 10;
int nY = 100;

String text = "ABCD 1234";
Rect rt = new Rect();
ptText.getTextBounds(text, 0, text.length(), rt);

rt.set(nX, nY-rt.height(), nX+rt.width(), nY);

canvas.drawRect(rt, ptRound);
canvas.drawText(text, nX, nY, ptText);




출력결과 Rect로 받아온값의 영역이 Text영역과 정확하게 일치한다
그런데 이때 영문과 숫자가 아닌 특수기호나 한글을 추가한다면
결과는 어떻게 될까?



String text = "ABC1234 한글출력 *_()";
Rect rt = new Rect();
ptText.getTextBounds(text, 0, text.length(), rt);

rt.set(nX, nY-rt.height(), nX+rt.width(), nY);

canvas.drawRect(rt, ptRound);
canvas.drawText(text, nX, nY, ptText);

 

텍스트에 들어가는 내용만 수정해주었다.
한글과 특수문자의 위치가 맞지않는것을 확인할수 있다.



이 이유는 getTextBounds 함수에 있다
getTextBounds 함수로 읽어온 값을 확인해보면
top 값은 음수이고 bottom 값은 0 또는 양수값이 들어오는걸 확인할 수 있다.
bottom 값이 0이상이 올경우가 바로 특수문자나 한글을 사용하였을때 발생하게 되는것이다.


따라서 getTextBounds 좌표체계는 다음과같다.

 





그렇다면 이제 Rect 값을 텍스트에 정확히 맞추어 보자


int nX = 10;
int nY = 100;

String text = "ABC1234 한글출력 *_()";
Rect rt = new Rect();
ptText.getTextBounds(text, 0, text.length(), rt);

rt.set(nX, nY + rt.top, nX + rt.width(), nY + rt.bottom);

canvas.drawRect(rt, ptRound);
canvas.drawText(text, nX, nY, ptText);

 


자 이제 화면에 출력되는 텍스트 영역을 완벽하게 구하였다.
물론 기초적이고 이미 다들 알고있을지도 모르지만
누군가 이문제로 인해 시간낭비할걸 막기위해 작성하였다.

신고
Posted by 레드오이

티스토리 툴바