[Android] 맨날 까먹는 runOnUiThread 사용예

통신을 통해 데이터를 스레드를 통해 딱… 가져오고 난 후 동일한 스레드에서 바로 Spinner 등과 같은 UI에 데이터를 설정하시면 우에엑~~ 하고 구토를 하시는 안드로이드님.

UI 단에 데이터를 설정할 수 있는 권한은 오직 UI 스레드, 즉 메인 스레드만이 하실 수 있는 전지전능하신 권한이므로 감히 자식 스레드에서는 기도를 통해 소원을 빌어야 합니다. 안드로이드님께서는 이러한 기도를 runOnUiThread라는 Context의 매서드를 통해 가능하게 하옵시고..

아래와 같은 예제를 통해 기도 방법을 메모하고자 합니다.

String strJSON = event.getResultJSON();

if(strJSON != null) {
    if(event.getRequestId().compareTo("행정구") == 0) {
        JSONArray array = (JSONArray)JSONValue.parse(strJSON);
        Iterator iter = array.iterator();
				
        final ArrayList list = new ArrayList();
        
        while(iter.hasNext()) {
            JSONObject obj = (JSONObject)iter.next();
            Set keySet = obj.keySet();
            Iterator keyIter = keySet.iterator();
            while(keyIter.hasNext()) {
            Object key = keyIter.next();
            Object val = obj.get(key);
            list.add(val);
        }
    }	
				
    Collections.sort(list);
				
    this.runOnUiThread(
        new Runnable() {
            @Override
            public void run() {
                Spinner spGuName = (Spinner)findViewById(R.id.spGuName);
                ArrayAdapter<Object> adapter = new ArrayAdapter<Object>(
                    ActivitySearchLocation.this, 
                    R.layout.custom_simple_dropdown_item_1line, list.toArray()
                );
                spGuName.setAdapter(adapter);						
            }
        });
    }
}

위의 코드는 데이터를 가져오는 통신 스레드에서 실행되는 코드이고 23번째 줄이 바로 ‘기도’에 해당합니다. 정작 중요한 내용보다 부수적인 내용이 더 많은 코드이지만.. 나중을 위해 Keep 해 둡니다. 참고로 가져온 데이터를 배열로 저장하고 이를 Collections 클래스의 정적 함수인 sort를 통해 정렬하고 있습니다.

[Andorid] 항상 까먹는 Spinner 항목값 설정

안드로이드는 뭐 하나 하려면 제법 손이 많이 갑니다.. 스피너에 항목값 리스트를 할당하는 것도 다른 툴에 비해 갑절이나 많은 코드를 작성해야 합니다.

String[] facilityList = { 
    "공급배관", "사용자배관", "공급밸브", "정압기", "테스트박스", 
    "로케이트박스", "정류기", "배류기", "수취기", "검지공" 
};
		
Spinner spFacilityType = (Spinner)findViewById(R.id.spFacilityType);
ArrayAdapter<string> adapter = new ArrayAdapter<string>(
    this, 
    android.R.layout.simple_spinner_dropdown_item, 
    facilityList);
spFacilityType.setAdapter(adapter);
spFacilityType.setSelection(0);

그런데 말입니다… 이렇게 해서 만들어진 스피너의 생김새가 다소 촌스럽습니다. 바로 아래처럼…

사용자 삽입 이미지

표시되는 항목들의 높이가 너무 높아 보이지 않나요? 이 항목의 높이값을 조절하기 위해 위의 코드 중 9번줄의 코드를 변경했는데 전체 코드를 다시 보면 다음과 같습니다.

String[] facilityList = { 
    "공급배관", "사용자배관", "공급밸브", "정압기", "테스트박스", 
    "로케이트박스", "정류기", "배류기", "수취기", "검지공" 
};
		
Spinner spFacilityType = (Spinner)findViewById(R.id.spFacilityType);
ArrayAdapter<string> adapter = new ArrayAdapter<string>(
    this, 
    R.layout.custom_simple_dropdown_item_1line, 
    facilityList);
spFacilityType.setAdapter(adapter);
spFacilityType.setSelection(0);

결과는 다음과 같습니다

사용자 삽입 이미지

이를 위해 여기서 추가한 리소스가 하나 있습니다. 바로 custom_simple_dropdown_item_1line.xml인데요. 그 내용은 다음과 같습니다.



이상 맨날 까먹어 고생하는 코드를 정리해 보았습니다.

[C#] 지정된 폴더(Folder)에서 파일명(File Name) 목록(List) 얻기

C#에서 지정된 폴더에 담긴 파일명의 목록을 얻는 코드입니다.

String FolderName = tbFolder.Text;
System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(FolderName);
foreach (System.IO.FileInfo File in di.GetFiles())
{
    if (File.Extension.ToLower().CompareTo(".xrv") == 0)
    {
        String FileNameOnly = File.Name.Substring(0, File.Name.Length - 4);
        String FullFileName = File.FullName;

        MessageBox.Show(FullFileName + " " + FileNameOnly);
    }
}

1번 코드에서 파일명 목록을 얻고자 하는 폴더명이 지정됩니다. 그리고 5번에서 확장자가 .xrv 인 파일만을 필터링합니다. 그리고 7번은 오직 파일명(경로와 확장자를 제외)만을 얻습니다. 끝으로 8번은 파일명의 전체 이름(경로와 확장자를 포함)을 얻습니다.

폴더 안의 서브 폴더를 처리하기 위해서는 DirectoryInfo의 GetDirectories 매서드를 사용하여 서브 폴더명의 리스트를 얻어와 처리하면 됩니다.

[Android] ViewFlipper에서 View의 전환에 대한 좌우 애니메이션

ViewFlipper을 사용해 여러 개의 뷰를 전환할 수 있는데요. 기본적으로 제공되는 안드로이드에서는 뷰의 전환이 왼쪽에서 오른쪽으로만 됩니다. 이는 안드로이드에서 제공하는 애니메이션 리소스가 왼쪽에서 오른쪽으로 전환되는 것만을 제공하기 때문입니다. 이 애니메이션 리소스는 android.R.anim.slide_in_left와 android.R.anim.slide_out_right입니다.

여기서 오른쪽에서 왼쪽으로 뷰의 전환이 이뤄지는 애니메이션을 위해서는 slide_in_right.xml와 slide_out_left.xml을 직접 추가하였고 해당 파일의 내용은 첨부 파일을 참고하시기 바랍니다.

실행 결과는 아래와 같습니다.

끝으로 전체 소스 코드를 다운로드 받을 수 있는 URL은 아래와 같습니다.