다국어 지원시 시스템 언어 설정 말고 앱에서 언어설정하기

Posted by 빵빵빵
2019/05/30 19:03 전산(컴퓨터)/안드로이드



안드로이드에서는 다국어 설정을 기본적으로 제공하고 있다.

그런데.... 시스템에서 언어를 변경해야 하는 방식으로 프로그래밍을 하면 전체 시스템 언어가 바뀌어서 여간 불편한 것이 아니다.

그래서 앱에만 적용되도록 바꿔주는 방법을 알아보도록 하자!!!


  1. // 로케일을 영어로 설정  
  2. Locale en = Locale.US;  
  3. // 환경설정 가져오기  
  4. Configuration config = new Configuration( );  
  5. // 환경설정 값에서 지역설정을 영어로 변경  
  6. config.locale = en;  
  7. // 리소스를 변경된 지역설정을 기준으로 갱신하기  
  8. getResources( ).updateConfiguration( config, getResources( ).getDisplayMetrics( ) );  

로케일이 변경된 다음에는 invalidateViews( ) 를 호출해줘야 변경된 언어로 화면이 갱신된다.

다음은 참고코드
출처 : https://stackoverflow.com/questions/5244889/load-language-specific-string-from-resource
  1. package com.my.package.localisation;  
  2.   
  3. <div>  
  4. import android.content.Context;  
  5. import android.content.res.AssetManager;  
  6. import android.content.res.Configuration;  
  7. import android.content.res.Resources;  
  8. import android.os.Build;  
  9. import android.support.annotation.NonNull;  
  10. import android.util.DisplayMetrics;  
  11.   
  12. import java.util.Formatter;  
  13. import java.util.Locale;  
  14.   
  15. /** 
  16.  * Class to manage fetching {@link Resources} for a specific {@link Locale}. API levels less 
  17.  * than {@link Build.VERSION_CODES#JELLY_BEAN_MR1} require an ugly implementation. 
  18.  * <p/> 
  19.  * Subclass extends {@link Resources} in case of further functionality requirements. 
  20.  */  
  21. public class MyResources {  
  22.   
  23.     private final Context mContext;  
  24.     private final AssetManager assetManager;  
  25.     private final DisplayMetrics metrics;  
  26.     private final Configuration configuration;  
  27.     private final Locale targetLocale;  
  28.     private final Locale defaultLocale;  
  29.   
  30.     public MyResources(@NonNull final Context mContext, @NonNull final Locale defaultLocale,  
  31.                          @NonNull final Locale targetLocale) {  
  32.   
  33.         this.mContext = mContext;  
  34.         final Resources resources = this.mContext.getResources();  
  35.         this.assetManager = resources.getAssets();  
  36.         this.metrics = resources.getDisplayMetrics();  
  37.         this.configuration = new Configuration(resources.getConfiguration());  
  38.         this.targetLocale = targetLocale;  
  39.         this.defaultLocale = defaultLocale;  
  40.     }  
  41.   
  42.     public String[] getStringArray(final int resourceId) {  
  43.   
  44.         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {  
  45.             configuration.setLocale(targetLocale);  
  46.             return mContext.createConfigurationContext(configuration).getResources().getStringArray(resourceId);  
  47.         } else {  
  48.             configuration.locale = targetLocale;  
  49.             final String[] resourceArray = new ResourceManager(assetManager, metrics, configuration).getStringArray(resourceId);  
  50.             configuration.locale = defaultLocale; // reset  
  51.             new ResourceManager(assetManager, metrics, configuration); // reset  
  52.             return resourceArray;  
  53.         }  
  54.     }  
  55.   
  56.     public String getString(final int resourceId) {  
  57.   
  58.         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {  
  59.             configuration.setLocale(targetLocale);  
  60.             return mContext.createConfigurationContext(configuration).getResources().getString(resourceId);  
  61.         } else {  
  62.             configuration.locale = targetLocale;  
  63.             final String resource = new ResourceManager(assetManager, metrics, configuration).getString(resourceId);  
  64.             configuration.locale = defaultLocale; // reset  
  65.             new ResourceManager(assetManager, metrics, configuration); // reset  
  66.             return resource;  
  67.         }  
  68.     }  
  69.   
  70.     private final class ResourceManager extends Resources {  
  71.         public ResourceManager(final AssetManager assets, final DisplayMetrics metrics, final Configuration config) {  
  72.             super(assets, metrics, config);  
  73.         }  
  74.   
  75.         /** 
  76.          * Return the string array associated with a particular resource ID. 
  77.          * 
  78.          * @param id The desired resource identifier, as generated by the aapt 
  79.          *           tool. This integer encodes the package, type, and resource 
  80.          *           entry. The value 0 is an invalid identifier. 
  81.          * @return The string array associated with the resource. 
  82.          * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 
  83.          */  
  84.         @Override  
  85.         public String[] getStringArray(final int id) throws NotFoundException {  
  86.             return super.getStringArray(id);  
  87.         }  
  88.   
  89.         /** 
  90.          * Return the string value associated with a particular resource ID, 
  91.          * substituting the format arguments as defined in {@link Formatter} 
  92.          * and {@link String#format}. It will be stripped of any styled text 
  93.          * information. 
  94.          * {@more} 
  95.          * 
  96.          * @param id         The desired resource identifier, as generated by the aapt 
  97.          *                   tool. This integer encodes the package, type, and resource 
  98.          *                   entry. The value 0 is an invalid identifier. 
  99.          * @param formatArgs The format arguments that will be used for substitution. 
  100.          * @return String The string data associated with the resource, 
  101.          * stripped of styled text information. 
  102.          * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 
  103.          */  
  104.         @NonNull  
  105.         @Override  
  106.         public String getString(final int id, final Object... formatArgs) throws NotFoundException {  
  107.             return super.getString(id, formatArgs);  
  108.         }  
  109.   
  110.         /** 
  111.          * Return the string value associated with a particular resource ID.  It 
  112.          * will be stripped of any styled text information. 
  113.          * {@more} 
  114.          * 
  115.          * @param id The desired resource identifier, as generated by the aapt 
  116.          *           tool. This integer encodes the package, type, and resource 
  117.          *           entry. The value 0 is an invalid identifier. 
  118.          * @return String The string data associated with the resource, 
  119.          * stripped of styled text information. 
  120.          * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 
  121.          */  
  122.         @NonNull  
  123.         @Override  
  124.         public String getString(final int id) throws NotFoundException {  
  125.             return super.getString(id);  
  126.         }  
  127.     }  
  128. }  


2019/05/30 19:03 2019/05/30 19:03

안드로이드에서 내가 Debug 모듈인지 체크하는 방법

Posted by 빵빵빵
2019/05/30 18:49 전산(컴퓨터)/안드로이드



ADT 17 이상에서

BuildConfig.DEBUG 상수값을 체크함으로 알 수 있다.

이 클래스는 컴파일시 generated 된다.

프로그래밍할때 다음과 같이 사용하면 편하다.

  1. if ( BuildConfig.DEBUG )   
  2. {  
  3.   // Debug 일때 사용할 코드  
  4. }  
  5. else  
  6. {  
  7.   // Release 일때 사용할 코드  
  8. }  


참고로 안드로이드 스튜디오에서 Run으로 실행시키나 Debug로 실행시키나 동일하게 BuildConfig.DEBUG 는 true 이다.

릴리즈 apk를 실행할때만 false이다.
2019/05/30 18:49 2019/05/30 18:49

C #의 예 : 무료 그리기 .NET GDI + 게이지 컨트롤 사용자 컨트롤

Posted by 빵빵빵
2018/10/08 15:44 전산(컴퓨터)/C#



C #의 예 : 무료 그리기 .NET GDI + 게이지 컨트롤 사용자 컨트롤

원문 : http://www.ucancode.net/Visual_C_MFC_Samples/CSharp_Example_Free_DOTNET_Gauge_Control_Draw_Source_Code.htm

자동 번역된 원문 : https://translate.googleusercontent.com/translate_c?depth=1&hl=en&ie=UTF8&prev=_t&rurl=translate.google.com&sl=auto&sp=nmt4&tl=ko&u=http://www.ucancode.net/Visual_C_MFC_Samples/CSharp_Example_Free_DOTNET_Gauge_Control_Draw_Source_Code.htm&xid=17259,15700023,15700043,15700124,15700149,15700186,15700191,15700201,15700214,15700215,15700218&usg=ALkJrhjgwnWG0C7Gdwu9LnRAInCVhzJabg

파일 보관 : 데모프로젝트, 소스


자동 번역된 원문 갈무리
[그림이 보이지 않으면 원문이 변경된 것임]


스크린 샷 - AquaGauge.gif

                                                    [그림1]

소개

쉽고 강력한 .NET GDI + 를 탐색하기 위해 .NET 사용자 정의 컨트롤 을 개발하기로 결정했습니다. .NET 2.0을 사용하여 개발 된이 간단한 계기 제어 는 모니터링 목적의 전체 범위를 충족시킬 수 있습니다. GDI +를 사용하여 광택 컨트롤을 개발하는 방법을 살펴 보겠습니다.

재정의 된 사용자 정의 컨트롤 메서드

일반적으로 사용자가 완전히 그려진 사용자 정의 컨트롤을 만들면 OnPaint  OnPaintBackground 메서드를 재정의해야 합니다. 또한 컨트롤 스타일을 적절하게 설정해야합니다. 이 공통 스타일은 this .SetStyle(ControlStyles.XXXXX, true/false); .

SupportsTransparentBackColor 이렇게하면 Gauge 컨트롤 이 true 설정된 경우 투명한 배경색을 지원할 수 true .
ControlStyles.ResizeRedraw 컨트롤 크기를 조정할 때 다시 칠할 수 있습니다.
ControlStyles.AllPaintingInWmPaint true 인 경우 컨트롤 은 깜박임을 줄이기 위해 WM_ERASEBKGND 창 메시지를 무시합니다 . 
이 스타일은 UserPaint 비트가 true 로 설정된 경우에만 적용해야 true .
ControlStyles.UserPaint true 컨트롤 은 운영 체제가 아니라 자체를 그립니다.
ControlStyles.OptimizedDoubleBuffer true 경우, 컨트롤은 화면에 직접적으로가 아니라 버퍼에 먼저 그려 지기 때문에 깜박임을 줄일 수 있습니다. 이 속성을 true 설정하면 AllPaintingInWmPaint  true 설정해야 true .

OnPaint  OnPaintBackground 메서드는 컨트롤을 다시 칠해야 할 때마다 호출됩니다. 예를 들어 컨트롤의 크기를 조정하거나 폼을 최소화하고 최대화하면 OnPaint 메서드가 호출됩니다.

OnPaintBackground 대 OnPaint

OnPaintBackground 는 Window의 배경 (그리하여 모양)을 OnPaintBackground 빠른 속도를 보장합니다. 반대로 OnPaint 는 세부 사항을 칠하고 개별 페인트 요청 을 다시 그려야하는 모든 영역을 포함하는 하나의 Paint 이벤트 로 결합하므로 속도가 느려질 수 있습니다 . 예를 들어 컨트롤에 그라디언트 색상의 배경을 그리려 는 경우 OnPaintBackground 를 호출 할 수 있습니다 .

OnPaintBackground 에는 이벤트와 같은 명명법이 있고 OnPaint 메서드 와 동일한 인수가 사용되지만 OnPaintBackground  true 이벤트 메서드 가 아닙니다 . PaintBackground 이벤트 가없고 PaintBackground 가 이벤트 대리자를 호출하지 않습니다. OnPaintBackground 메서드를 재정의 할 때 파생 클래스는 기본 클래스  OnPaintBackground 메서드 를 호출 할 필요가 없습니다 .

게이지 다이얼 그리기

먼저 다이얼을 그려 보는 법을 봅시다. 다이얼에는 눈금, 임계 값 표시기, 일부 텍스트 및 현재 값이 표시되어야합니다.

눈금을 그리 려면 원주에서 그려지 는 규칙의 위치를 ​​계산해야합니다. 다이얼에서 90도에서 270도 사이의 각도에서 0부터 10까지의 크기로 그려야 한다고 가정 해 봅시다. 이 경우도 (270-90 = 180)의 차이는 10 부분으로 나누어야합니다. 그려야 할 각 파트의 위치를 ​​찾으려면 다음 수식이 필요합니다.

  x = centerX + radius * cos (180 / partNo)   y = 중심 Y + 반경 * sin (180 / partNo) 

참고 : Math.Cos 또는 Math.Sin  사용할 때 각도를 라디안 단위로 지정해야합니다.

서클 수식

                             [그림2]

위치를 찾은 후 원주에 모든 유형의 눈금 표시를 그릴 수 있습니다. 나는 눈금으로 선을 그리기 로했다. 다이얼 영역은 자주 변경되지OnPaintBackground 재정의  OnPaintBackground 메서드 에서 그릴 수 있습니다 .

포인터 그리기

포인터를 자주 다시 칠할 필요가 있습니다. 따라서 OnPaint 메서드 에서 그리는 것이 좋습니다 . 포인터 위치를 찾는 것은 척도 그리기 의 논리와 같습니다. 포인터는 graphicsObj.FillPolygon() 메서드를 사용하여 그릴 수 있으며 현재 값을 나타내는 모든 각도로 변환 할 수 있습니다. 그렇지 않으면 현재 값에 대한 모든 변경 사항에 대해 포인터를 다시 그릴 수 있습니다.

광택을 그리기

광택을 그리는 것은 매우 간단합니다. 모든 다이얼과 포인터를 페인팅 한 후에 그라디언트 색상으로 두 개의 타원을 채우면됩니다.LinearGradientBrush 클래스는 그라디언트 칠을 그릴 수있는 기능을 제공합니다. 다이얼 위로 그라디언트 레이어를 설정하면 아래 그림과 같이 광택이 생깁니다.

광택

                                                         [그림3]

Aqua Gauge 컨트롤 사용하기

 Aqua Gauge 컨트롤 은 Windows에서 제공하는 다른 사용자 컨트롤로 사용할 수 있습니다. 다음은 요구 사항에 맞게이 게이지를 구성하는 데 사용할 수있는 컨트롤 관련 속성입니다.

속성 이름 유형 기술
DialColor Color 게이지의 배경색을 가져 오거나 Set .
DialText String 게이지 다이얼에 표시된 텍스트를 가져 오거나 Set 합니다.
EnableTransparentBackground bool 투명한 배경색을 사용하거나 사용하지 않도록 설정합니다. 참고 :이 옵션을 사용하면 성능이 저하되고 컨트롤이 깜박일 수 있습니다.
Glossiness float Glossiness의 강도를 Get 거나 Set .
MaxValue float s 또는 Set 게이지 스케일에 표시된 최대 값으로 가져옵니다.
MinValue float s 또는 Set 게이지 눈금에 표시된 최소값으로 가져옵니다.
NoOfDivisions int 게이지 눈금의 분할 수를 s 또는 Set 으로 지정합니다.
NoOfSubDivisions int s 나 Set 을 각 디비전에 대한 눈금에 표시되는 세분화 수로 가져옵니다.
RecommendedValue float 눈금에 s 또는 Set 권장 값으로 가져옵니다. 이것은 임계 영역을 그리기위한 피벗 점으로 사용됩니다.
ThresholdPercent float 눈금에서 임계 값 영역 비율을 가져 오거나 Set .
Value float 포인터가 가리킬 값을 가져 오거나 Set 합니다.

가볼만한 곳

우리가 많은 조작으로 이미지를 그릴 때마다 이미지 객체에 그려서 페인트하는 것이 좋습니다. 예를 들어 계기판을 그리려면 CPU를 많이 사용하는 작업이 필요합니다. 따라서 다이얼로그를 이미지 위에 그린 다음 graphicsObj.DrawImage() 사용하여 그릴 수 있습니다. 다이얼 속성을 변경할 때마다 이미지 개체를 다시 만들 수 있습니다. 성능이 향상됩니다.

2018/10/08 15:44 2018/10/08 15:44