Listview 내에서 arraylist 의 초성 검색 예제입니다.

참고 url

http://www.androidpub.com/45681


   


HangulUtils.cass 파일을 생성합니다.

/**
 * com.ziofront.utils
 * HangulUtils.java
 * Jiho Park 2009. 11. 27.
 *
 * Copyright (c) 2009 ziofront.com. All Rights Reserved.
 */
public class HangulUtils {

	private static String toHexString(int decimal) {
		Long intDec = Long.valueOf(decimal);
		return Long.toHexString(intDec);
	}

	public static final int HANGUL_BEGIN_UNICODE = 44032; // 가
	public static final int HANGUL_END_UNICODE = 55203; // 힣
	public static final int HANGUL_BASE_UNIT = 588;

	public static final int[] INITIAL_SOUND_UNICODE = { 12593, 12594, 12596,
			12599, 12600, 12601, 12609, 12610, 12611, 12613, 12614, 12615,
			12616, 12617, 12618, 12619, 12620, 12621, 12622 };

	public static final char[] INITIAL_SOUND = { 'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ', 'ㄹ',
			'ㅁ', 'ㅂ', 'ㅃ', 'ㅅ', 'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ' };

	/**
	 * 문자를 유니코드(10진수)로 변환 후 반환 한다.
	 * 
	 * @param ch
	 * @return
	 */
	public static int convertCharToUnicode(char ch) {
		return (int) ch;
	}

	/**
	 * 문자열을 유니코드(10진수)로 변환 후 반환 한다.
	 * 
	 * @param str
	 * @return
	 */
	public static int[] convertStringToUnicode(String str) {
		int[] unicodeList = null;
		if (str != null) {
			unicodeList = new int[str.length()];
			for (int i = 0; i < str.length(); i++) {
				unicodeList[i] = convertCharToUnicode(str.charAt(i));
			}
		}

		return unicodeList;
	}

	/**
	 * 유니코드(16진수)를 문자로 변환 후 반환 한다.
	 * 
	 * @param hexUnicode
	 * @return
	 */
	public static char convertUnicodeToChar(String hexUnicode) {
		return (char) Integer.parseInt(hexUnicode, 16);
	}

	/**
	 * 유니코드(10진수)를 문자로 변환 후 반환 한다.
	 * 
	 * @param unicode
	 * @return
	 */
	public static char convertUnicodeToChar(int unicode) {
		return convertUnicodeToChar(toHexString(unicode));
	}

	/**
	 * 
	 * @param value
	 * @return
	 */
	public static String getHangulInitialSound(String value) {
		StringBuffer result = new StringBuffer();
		int[] unicodeList = convertStringToUnicode(value);
		for (int unicode : unicodeList) {

			if (HANGUL_BEGIN_UNICODE <= unicode
					&& unicode <= HANGUL_END_UNICODE) {
				int tmp = (unicode - HANGUL_BEGIN_UNICODE);
				int index = tmp / HANGUL_BASE_UNIT;
				result.append(INITIAL_SOUND[index]);
			} else {
				result.append(convertUnicodeToChar(unicode));

			}
		}
		return result.toString();
	}

	public static boolean[] getIsChoSungList(String name) {
		if (name == null) {
			return null;
		}
		boolean[] choList = new boolean[name.length()];
		for (int i = 0; i < name.length(); i++) {
			char c = name.charAt(i);

			boolean isCho = false;
			for (char cho : INITIAL_SOUND) {
				if (c == cho) {
					isCho = true;
					break;
				}
			}
			choList[i] = isCho;
		}
		return choList;
	}

	public static String getHangulInitialSound(String value,
			String searchKeyword) {
		return getHangulInitialSound(value, getIsChoSungList(searchKeyword));
	}

	public static String getHangulInitialSound(String value, boolean[] isChoList) {
		StringBuffer result = new StringBuffer();
		int[] unicodeList = convertStringToUnicode(value);
		for (int idx = 0; idx < unicodeList.length; idx++) {
			int unicode = unicodeList[idx];

			if (isChoList != null && idx <= (isChoList.length - 1)) {
				if (isChoList[idx]) {
					if (HANGUL_BEGIN_UNICODE <= unicode
							&& unicode <= HANGUL_END_UNICODE) {
						int tmp = (unicode - HANGUL_BEGIN_UNICODE);
						int index = tmp / HANGUL_BASE_UNIT;
						result.append(INITIAL_SOUND[index]);
					} else {
						result.append(convertUnicodeToChar(unicode));
					}
				} else {
					result.append(convertUnicodeToChar(unicode));
				}
			} else {
				result.append(convertUnicodeToChar(unicode));
			}
		}

		return result.toString();
	}

	public static void main(String[] args) {
		for (char ch : HangulUtils.INITIAL_SOUND) {
			System.out.print(HangulUtils.convertCharToUnicode(ch) + ",");
		}
	}
}


ListView뷰를 구성합니다.

xml코드

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorBg">

    <android.support.v7.widget.RecyclerView
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:background="@color/colorBg"
        android:id="@+id/rv">
    </android.support.v7.widget.RecyclerView>

    <!-- no data -->
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="20dp"
        android:id="@+id/tv_noSearch"
        android:textColor="#000000"
        android:text="검색된 메모가 없습니다"
        android:visibility="invisible"
        android:textSize="16sp"/>
</RelativeLayout>


EditText 내에서의 TextWathcher 작업을 합니다.

search_view = (EditText) findViewById(R.id.search_view); search_view.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence c, int i, int i1, int i2) { setChangeListData(c.toString()); } @Override public void afterTextChanged(Editable editable) { } });


setChangeListData 메소드를 작성합니다.

public void setChangeListData(String searchKeyword) {
	if(searchKeyword != null) {
		if (searchKeyword.length() == 0) {
			setLoadListData(oriList);
		} else {
			List<ItemMemo> temp = new ArrayList<>();
			for(ItemMemo i : mList) {
				boolean isAdd = false;
				String iniName = HangulUtils.getHangulInitialSound(i.contents, searchKeyword);
				if (iniName.indexOf(searchKeyword) >= 0) {
					isAdd = true;
				}
				if(isAdd) {
					temp.add(i);
				}
			}
			setSearchData(temp);
		}
	} else {
		setLoadListData(oriList);
	}
}

private void setSearchData(List<ItemMemo> list) {
	lay_noData.setVisibility(View.GONE);
	tv_noSearch.setVisibility(View.GONE);
	if(list.size() == 0) {
		rv.setVisibility(View.INVISIBLE);
		tv_noSearch.setVisibility(View.VISIBLE);
	} else {
		rv.setVisibility(View.VISIBLE);
		mAdapter.swap(list);
	}
}


SNS에서 게시물 같은 곳에 특정시간을 불러와서 현재시간이랑 비교 후 분,시,일,월,년 계산 해서

스트링 반환하는 예제입니다.


 코드 사용

regTime은 계산할 시간이고,

curTime은 현재 시간입니다.

/** 몇분전, 방금 전, */
private static class TIME_MAXIMUM{
	public static final int SEC = 60;
	public static final int MIN = 60;
	public static final int HOUR = 24;
	public static final int DAY = 30;
	public static final int MONTH = 12;
}
public static String formatTimeString(long regTime) {
	long curTime = System.currentTimeMillis();
	long diffTime = (curTime - regTime) / 1000;
	String msg = null;
	if (diffTime < TIME_MAXIMUM.SEC) {
		msg = "방금 전";
	} else if ((diffTime /= TIME_MAXIMUM.SEC) < TIME_MAXIMUM.MIN) {
		msg = diffTime + "분 전";
	} else if ((diffTime /= TIME_MAXIMUM.MIN) < TIME_MAXIMUM.HOUR) {
		msg = (diffTime) + "시간 전";
	} else if ((diffTime /= TIME_MAXIMUM.HOUR) < TIME_MAXIMUM.DAY) {
		msg = (diffTime) + "일 전";
	} else if ((diffTime /= TIME_MAXIMUM.DAY) < TIME_MAXIMUM.MONTH) {
		msg = (diffTime) + "달 전";
	} else {
		msg = (diffTime) + "년 전";
	}
	return msg;
}


적용 후


현재 fragment 가져오기
및 instanceof 로 fragment 구분하기

코드 사용

// 현재 프레그멘트 가져오기
Fragment fragment = getFragmentManager().findFragmentById(R.id.frame);
if(fragment instanceof MyFragment) {
	// todo 	
}


android cardview background color 적용하기


java 코드

setCardBackgroundColor 메소드를 사용하시면 됩니다.

int color = R.color.color_black;

CardView lay_frame = (CardView) itemView.findViewById(R.id.lay_frame);
lay_frame.setCardBackgroundColor(ContextCompat.getColor(getActivity(), res));


or xml 코드

cardBackgroundColor 애튜리뷰트를 사용하면 됩니다.

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:foreground="?android:attr/selectableItemBackground"
    android:id="@+id/lay_frame"
    android:layout_marginTop="8dp"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"
    card_view:cardCornerRadius="5dp"
    card_view:cardBackgroundColor="@color/color_black">



지도를 사용하다가 현재 이미지를 불러와서 파일로 저장을 한다던지,

공유 기능에 붙일 것인지 유용하게 사용할수 있습니다.


java 코드

final ImageView iv_capture = (ImageView) view.findViewById(R.id.iv_capture);
Button button_capture = (Button) view.findViewById(R.id.button_capture);
button_capture.setOnClickListener(new View.OnClickListener() {
	@Override
	public void onClick(View view) {
		GoogleMap.SnapshotReadyCallback callback = new GoogleMap.SnapshotReadyCallback() {
			@Override
			public void onSnapshotReady(Bitmap snapshot) {
				iv_capture.setImageBitmap(snapshot);
			}
		};
		mGoogleMap.snapshot(callback);
	}
});


적용 화면




actionbar 아래 shodow 없애기

AppBarLayout 내에 app:evlevation="0dp" 를 추가하면 됩니다.


xml 코드 수정 

<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" app:elevation="0dp" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay" >

변경전



변경후


Actionbar home, arrow, title color 변경하는 방법입니다.

style 테마로 지정하는 방법도 있겠지만, 지금 경우는 버튼을 눌렀을 경우 유동적으로 변할 수 

있도록 java 코드로 작성하였습니다.


color 값을 준비합니다.

    <color name="color_memo1">#03a9f3</color>
    <color name="color_memo2">#8bc349</color>
    <color name="color_memo3">#ffc108</color>
    <color name="color_memo4">#ff5720</color>
    <color name="color_memo5">#9e9e9e</color>

    <color name="color_text1">#0000ff</color>
    <color name="color_text2">#259b20</color>
    <color name="color_text3">#ff9700</color>
    <color name="color_text4">#ff0000</color>
    <color name="color_text5">#ffffff</color>


코드 내용

private void setColorBt(int index) {

	ib_color_1.setBackgroundResource(R.color.color_memo1);
	ib_color_2.setBackgroundResource(R.color.color_memo2);
	ib_color_3.setBackgroundResource(R.color.color_memo3);
	ib_color_4.setBackgroundResource(R.color.color_memo4);
	ib_color_5.setBackgroundResource(R.color.color_memo5);

	int colorBgId = R.color.color_memo1;
	int colorTxtId = R.color.color_text1;
	if(index == 0) {
		ib_color_1.setBackgroundResource(R.drawable.bt_color_frame);
	} else if(index == 1) {
		colorBgId = R.color.color_memo2;
		colorTxtId = R.color.color_text2;
		ib_color_2.setBackgroundResource(R.drawable.bt_color_frame);
	} else if(index == 2) {
		colorBgId = R.color.color_memo3;
		colorTxtId = R.color.color_text3;
		ib_color_3.setBackgroundResource(R.drawable.bt_color_frame);
	} else if(index == 3) {
		colorBgId = R.color.color_memo4;
		colorTxtId = R.color.color_text4;
		ib_color_4.setBackgroundResource(R.drawable.bt_color_frame);
	} else if(index == 4) {
		colorBgId = R.color.color_memo5;
		colorTxtId = R.color.color_text5;
		ib_color_5.setBackgroundResource(R.drawable.bt_color_frame);
	}
	lay_frame.setBackgroundResource(colorBgId);

	setActionBarColor(colorBgId, colorTxtId);
}

public void setActionBarColor(int colorBgId, int colorId) {

	int colorBg = ContextCompat.getColor(getBaseContext(), colorBgId);
	int colorText = ContextCompat.getColor(getBaseContext(), colorId);

	ActionBar bar = getSupportActionBar();
	if(bar != null) {
		// bar 백그라운드 색상 변경
		bar.setBackgroundDrawable(new ColorDrawable(colorBg));

		// 타이틀 색상 변경
		Spannable text = new SpannableString(bar.getTitle());
		text.setSpan(new ForegroundColorSpan(colorText), 0, text.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
		bar.setTitle(text);

		// 홈,화살표 버튼 색상 변경
		mToggle.getDrawerArrowDrawable().setColor(colorText);
	}
}


결과 화면

    


데이터를 한꺼번에 집어 넣기 위해 편리한 방법을 검색,

jexcelapi:jxl 라이브러리를 이용하여 테스트 코드를 만들어 보았습니다.


주의사항! 

엑셀 파일은 Excel 97 ~ 2003 통합 문서 (.xls) 만 지원가능합니다.


엑셀파일 준비하여 앱 내의 > src > main > assets 폴더에 엑셀파일 추가 (없으면 디렉토리 생성 하시면 됩니다.) 

1. 프로젝트에서 > Open Module Settings 를 선택합니다.



2. app > Dependencies > 하단 (+) 버튼 클릭 > jxl 로 검색 후 적용


3. 코드 적용

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        try {
            InputStream is = getBaseContext().getResources().getAssets().open("my_excel.xls");
            Workbook wb = Workbook.getWorkbook(is);

            if(wb != null) {
                Sheet sheet = wb.getSheet(0);   // 시트 불러오기
                if(sheet != null) {
                    int colTotal = sheet.getColumns();    // 전체 컬럼
                    int rowIndexStart = 1;                  // row 인덱스 시작
                    int rowTotal = sheet.getColumn(colTotal-1).length;

                    StringBuilder sb;
                    for(int row=rowIndexStart;row<rowTotal;row++) {
                        sb = new StringBuilder();
                        for(int col=0;col<colTotal;col++) {
                            String contents = sheet.getCell(col, row).getContents();
                            sb.append("col"+col+" : "+contents+" , ");
                        }
                        Log.i("test", sb.toString());
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (BiffException e) {
            e.printStackTrace();
        }
    }
}



4. 완료 화면 로그



Bitmap 이미지 모서리 round 처리하기


코드 사용

Button button2 = (Button) findViewById(R.id.button2); button2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Bitmap bm = ((BitmapDrawable) imageView.getDrawable()).getBitmap(); imageView.setImageBitmap(getRoundedCornerBitmap(bm, 20)); } });

호출

/* 비트맵 모서리 둥글게*/
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int px) {
	Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
	Canvas canvas = new Canvas(output);
	final int color = 0xff424242;
	final Paint paint = new Paint();
	final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
	final RectF rectF = new RectF(rect);
	final float roundPx = px;
	paint.setAntiAlias(true);
	canvas.drawARGB(0, 0, 0, 0);
	paint.setColor(color);
	canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
	paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
	canvas.drawBitmap(bitmap, rect, rect, paint);
	return output;
}


변경 전


변경 후


사진을 찍던, 갤러리에 보관이 되던 썸네일은 항상 internal 에 보관이 되어있습니다.

리스트에서 사용을 앱의 성능 향상을 위해서는 썸네일을 쓰는 것이 좋습니다.


코드 사용

xml 코드

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="갤러리 호출"
        tools:layout_editor_absoluteX="16dp"
        tools:layout_editor_absoluteY="16dp" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />

java 코드

public class MainActivity extends AppCompatActivity {

    private static final int PICK_FROM_ALBUM = 1;
    ImageView imageView;

    //권한 추가
    private static final int REQUEST_PERMISSIONS = 1;
    private static final String[] MY_PERMISSIONS = {
            Manifest.permission.READ_EXTERNAL_STORAGE
    };
    public boolean hasAllPermissionsGranted() {
        for (String permission : MY_PERMISSIONS) {
            if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, MY_PERMISSIONS, REQUEST_PERMISSIONS);
                return false;
            }
        }
        return true;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if (requestCode == REQUEST_PERMISSIONS) {
            int index = 0;
            for (String permission : permissions) {
                if(permission.equalsIgnoreCase(Manifest.permission.READ_EXTERNAL_STORAGE) && grantResults[index] == PackageManager.PERMISSION_GRANTED) {
                    getGalley();
                    break;
                }
                index++;
            }
            return;
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageView = (ImageView) findViewById(R.id.imageView);
        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
               if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                    boolean permission = hasAllPermissionsGranted();
                    Log.e("test","permission : "+permission);
                    if(!permission)
                    	return;
                }
		getGalley();
            }
        });
    }

    private void getGalley() {
        Intent intent = new Intent(Intent.ACTION_PICK,  android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        intent.setType(MediaStore.Images.Media.CONTENT_TYPE);
        startActivityForResult(intent, PICK_FROM_ALBUM);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == PICK_FROM_ALBUM) {
            if (resultCode == Activity.RESULT_OK) {
                Log.d("test","data : "+data);
                if(data != null) {
                    Uri returnImg = data.getData();
                    if("com.google.android.apps.photos.contentprovider".equals(returnImg.getAuthority())) {
                        for(int i=0;i<returnImg.getPathSegments().size();i++) {
                            String temp = returnImg.getPathSegments().get(i);
                            if(temp.startsWith("content://")) {
                                returnImg = Uri.parse(temp);
                                break;
                            }
                        }
                    }
                    // 썸네일 가져오기
                    Bitmap bm = getThumbNail(returnImg);
                    imageView.setImageBitmap(bm);
                }
            }
        }
    }

    private Bitmap getThumbNail(Uri uri) {
        Log.d("test","from uri : "+uri);
        String[] filePathColumn = {MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA, MediaStore.Images.Media.TITLE/*, MediaStore.Images.Media.ORIENTATION*/};

        ContentResolver cor = getContentResolver();
        //content 프로토콜로 리턴되기 때문에 실제 파일의 위치로 변환한다.
        Cursor cursor = cor.query(uri, filePathColumn, null, null, null);

        Bitmap thumbnail = null;
        if(cursor != null) {
            cursor.moveToFirst();
            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            long ImageId = cursor.getLong(columnIndex);
            if(ImageId != 0) {
                BitmapFactory.Options bmOptions = new BitmapFactory.Options();
                thumbnail = MediaStore.Images.Thumbnails.getThumbnail(
                        getContentResolver(), ImageId,
                        MediaStore.Images.Thumbnails.MINI_KIND,
                        bmOptions);
            } else {
                Toast.makeText(this, "불러올수 없는 이미지 입니다.", Toast.LENGTH_LONG).show();
            }
            cursor.close();
        }
        return thumbnail;
    }
}

작업 전


썸네일 불러오기 후

+ Recent posts