안드로이드에서 객체 정렬(sort) 하기


Arrays.sort() 메소드를 이용하면 배열 안의 원소들을 정렬할수 있다.

그러나 객체가 배열의 원소일때는 이 메소드로는 처리가 안된다.

정렬 대상이 객체(클래스의 객체)일 경우는 Comparable이라는 인터페이스를 통해서 가능하다.


이름(name)과 나이(age)라는 2개의 필드를 가진 People라는 클래스가 있다고 가정해 보자.

이 클래스를 정렬할려면 Comparable라는 인터페이스를 통해서 어떻게 구현하는지 살펴본다.


public class People implements Comparable<People>{

private String name;

private int age;

public People(String _name, int _age){

this.name = _name;

this.age = _age;

}

public String getName(){

return this.name;

}

public int getAge(){

return this.age;

}

public int compareTo(People _people){

//여긴 이름을 기준으로 정렬

//이건 내림 차순

//문자열은 이런 식으로 가능

// return this.name.compareTo(_people.name); 

//이건 오름차순

//문자열은 이런 식으로 가능

// return _people.name.compareTo(this.name);

//여기서부터는 나이를 기준으로 정렬

//이건 내림 차순

//숫자는 위의 compareTo()로 안되고 다음과 같이 처리 해야됨

if (this.age < _people.age){

// return -1; //이렇게 하면 내림 차순

return 1; //이렇게 하면 오름 차순

} else if (this.age == _people.age){

return 0;

} else {

// return 1; //이렇게 하면 내림 차순

return -1; //이렇게 하면 오름 차순

}

}

}


People이라는 객체를 사용하는 곳은 다음과 같다.

보통 Listview의 각 항목들을 보여줄때 이름을 기준으로나 혹은 나이를 기준으로 내림차순 혹은 오름 차순으로 보여주고자 할때 Comparable 인터페이스를 활용하면 간단히 처리할 수 있다.

여기서는 단지 화면의 TextView에 보여주는 기능을 구현해본다.


public class ExObjectSortActivity extends Activity {

private TextView txt;

private ArrayList<People> arrList;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.ex_object_sort);

txt = (TextView)findViewById(R.id.txt);

arrList = new ArrayList<People>();

arrList.add(new People("홍길동", 15));

arrList.add(new People("고길동", 25));

arrList.add(new People("둘리", 12));

arrList.add(new People("챨리", 32));

arrList.add(new People("강감찬", 120));

String rt = "";

String str = "";

//기존 저장된 순서대로 출력

for(int i=0; i<arrList.size(); i++){

str += arrList.get(i).getName()+" - "

                                     +arrList.get(i).getAge()+"\n";

}

str += "\n\n\n";

//Comparable에서 지정된 대로(내림차순 혹은 오름차순) 정렬됨

Collections.sort(arrList);

//정렬된 결과를 출력하기

for(int i=0; i<arrList.size(); i++){

str += arrList.get(i).getName()+" - "

                                     +arrList.get(i).getAge()+"\n";

}

txt.setText(str);

}

}


ex_object_sort.xml 레이아웃은 다음과 같이 되어 있다.


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:layout_margin="20dp"

    tools:context="${relativePackage}.${activityClass}" >


    <TextView

        android:id="@+id/txt"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:textColor="#000000"

        android:textSize="20sp" />

</RelativeLayout>




자바 혹은 안드로이드를 개발할 때 로그 정보는 더 없이 유용한 정보이다.

난공불락 같아 보이는 에러도 로그를 출력해 보면 거의 대부분 문제를 해결하게 된다.

이클립스로 개발 한다면 로그 정보를 보는 방법은 매우 간단하다.

그런에 여기서는 로그의 정보를 파일로 저장하는 방법에 대해서 살펴본다.


우선 adb.exe가 설치되어 있는 위치로 이동해서 도스 창(커맨더 창)을 adb가 있는 위치에서 연다.

그리고 logcat을 저장하기 위해 사용할수 있는 명령어 형태는 다음과 같다.


Usage: logcat [options] [filterspecs]


options include:

  -s              Set default filter to silent.

                  Like specifying filterspec '*:s'

  -f <filename>   Log to file. Default to stdout

  -r [<kbytes>]   Rotate log every kbytes. (16 if unspecified). Requires -f

  -n <count>      Sets max number of rotated logs to <count>, default 4

  -v <format>     Sets the log print format, where <format> is one of:

                  brief process tag thread raw time threadtime long

  -c              clear (flush) the entire log and exit

  -d              dump the log and then exit (don't block)

  -t <count>      print only the most recent <count> lines (implies -d)

  -t '<time>'     print most recent lines since specified time (implies -d)

  -T <count>      print only the most recent <count> lines (does not imply -d)

  -T '<time>'     print most recent lines since specified time (not imply -d)

                  count is pure numerical, time is 'MM-DD hh:mm:ss.mmm'

  -g              get the size of the log's ring buffer and exit

  -b <buffer>     Request alternate ring buffer, 'main', 'system', 'radio',

                  'events', 'crash' or 'all'. Multiple -b parameters are

                  allowed and results are interleaved. The default is

                  -b main -b system -b crash.

  -B              output the log in binary.

  -S              output statistics.

  -G <size>       set size of log ring buffer, may suffix with K or M.

  -p              print prune white and ~black list. Service is specified as

                  UID, UID/PID or /PID. Weighed for quicker pruning if prefix

                  with ~, otherwise weighed for longevity if unadorned. All

                  other pruning activity is oldest first. Special case ~!

                  represents an automatic quicker pruning for the noisiest

                  UID as determined by the current statistics.

  -P '<list> ...' set prune white and ~black list, using same format as

                  printed above. Must be quoted.


filterspecs are a series of 

  <tag>[:priority]


where <tag> is a log component tag (or * for all) and priority is:


  V    Verbose

  D    Debug

  I    Info

  W    Warn

  E    Error

  F    Fatal

  S    Silent (supress all output)


'*' means '*:d' and <tag> by itself means <tag>:v

If not specified on the commandline, filterspec is set from ANDROID_LOG_TAGS.

If no filterspec is found, filter defaults to '*:I'

If not specified with -v, format is set from ANDROID_PRINTF_LOG

or defaults to "brief"


로그 정보에는 몇가지 종류가 있다.

v : 온갖 종류의 로그 전부다를 보여준다.

d, e, ...


그 중에서 여기서는 e에 대한 정보만을 출력하는 정보만을 파일로 저장해 본다.

다른 필터들(d, v, i...)도 동일한 방식으로 저장한다.

사용 방식은 다음과 같다.


Usage: logcat [options] [filterspecs]


따라서 다음과 같이 하면된다.


adb logcat *:e > D:\temp\kkk.txt


위와 같이 명령하면 D:\temp 폴더 아래에 kkk.txt라는 이름으로 로그 중 e(에러) 정보만을 파일로 저장한다.





JSP의 자바빈(JavaBeans) 사용시 <jsp:setProperty ... property="*"에 대해서


jsp:setProperty에서 property="*"는 개발자들의 손가락의 수고를 많이 덜어주는 유용한 기능이다.

JavaBeans가 다음과 같이 구성되어 있다고 할때


package com.joe.test;


public class Student {

private String sName;

private int sAge;

private int sGrade;

private int sID;

public Student() {

}


public String getsName() {

return sName;

}


public void setsName(String sName) {

this.sName = sName;

}


... 나머지는 생략 ...

}



JSP에서 자바빈 사용시 원래는 다음과 같은 방식이다.


<%@ page language="java" contentType="text/html; charset=EUC-KR"

    pageEncoding="EUC-KR"%>

<jsp:useBean id="myStudent" class="com.joe.test.Student" scope="page"/>  


... 중략 ...


<jsp:setProperty name="myStudent" property="sName" value="고길동"/>

<jsp:setProperty name="myStudent" property="sAge" value="10" />

<jsp:setProperty name="myStudent" property="sGrade" value="3"/>

<jsp:setProperty name="myStudent" property="sID" value="12345"/>


그런데 만일 폼으로부터 JSP가 JavaBeans를 이용해서 값을 넘겨 받는다면 이런식으로 처리된다.

form의 내용이 만일 다음과 같다고 할때


<form action="showStudent.jsp" method="post">

이름 : <input type="text" name="name" size="10"><br/>

나이 : <input type="text" name="age" size="3"><br/>

학년 : <input type="text" name="grade" size="3"><br/>

학번 : <input type="text" name="id" size="10"><br/>

<p/>

<input type="submit" value="전송">&nbsp;&nbsp;&nbsp;<input type="reset" value="취소">

</form>


showStudent.jsp에서는 다음과 같이 값을 받는다.


<%@ page language="java" contentType="text/html; charset=EUC-KR"

    pageEncoding="EUC-KR"%>

<jsp:useBean id="myStudent" class="com.joe.test.Student" scope="page"/>


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">

<title>Insert title here</title>

</head>

<body>

     

<jsp:setProperty name="myStudent" property="sName" param="name"/>

<jsp:setProperty name="myStudent" property="sAge" param="age"/>

<jsp:setProperty name="myStudent" property="sGrade" param="grade"/>

<jsp:setProperty name="myStudent" property="sID" param="id"/>


학생이름 : <jsp:getProperty name="myStudent" property="sName"/><br/>

학생나이 : <jsp:getProperty name="myStudent" property="sAge"/><br/>

학&nbsp;&nbsp;&nbsp;년 <jsp:getProperty name="myStudent" property="sGrade"/><br/>

학생번호 : <jsp:getProperty name="myStudent" property="sID"/> 

</body>

</html>


그런데 만일 form의 파라미터 이름을 JabaBeans에 있는 변수명과 동일하게 한다면


<form action="showStudent.jsp" method="post">

이름 : <input type="text" name="sName" size="10"><br/>

나이 : <input type="text" name="sAge" size="3"><br/>

학년 : <input type="text" name="sGrade" size="3"><br/>

학번 : <input type="text" name="sID" size="10"><br/>

<p/>

<input type="submit" value="전송">&nbsp;&nbsp;&nbsp;<input type="reset" value="취소">

</form>


showStudent.jsp에서는 아래 4개의 코드를 


<jsp:setProperty name="myStudent" property="sName" param="sName"/>

<jsp:setProperty name="myStudent" property="sAge" param="sAge"/>

<jsp:setProperty name="myStudent" property="sGrade" param="sGrade"/>

<jsp:setProperty name="myStudent" property="sID" param="sID"/>


다음과 같이 간단히 사용할수 있다(showStudent.jsp의 나머지 내용은 동일).


<jsp:setProperty name="myStudent" property="*" />





※ Oracle Database 11g Express Edition 중심으로

자바에서 Oracle DB를 사용할 때 JDBC 라이브러리를 사용하게 되는데 이때 JDBC를 사용하기 위해 몇가지 필요한 정보가 있다. 즉 JDBC를 통해 Oracle DB에 connection하기 위해 몇 가지 필요한 정보가 있다. 대표적으로
Oracle 사용자 계정에 대한 id, password...
그 중에서 Oracle database에 대한 url 정보가 있다.
대체로 다음과 같은 형태이다.

jdbc:oracle:thin:@localhost:1521:xe

이것이 무엇을 의미하는지에 대해서 살펴본다.
이에 대한 프로토타입은 다음과 같다.

jdbc:oracle:driver_type:[username/password]@[//]host_name[:port][/XE]

위의 프로토타입으로부터 아래 정보를 해석해 보면 다음과 같다.

jdbc:oracle:thin:@localhost:1521:xe

-. jdbc:oracle:thin은 사용하는 JDBC드라이버가 thin 타입을 의미한다. 자바용 오라클 JDBC드라이버는 크게 두가지가 있는데 하나는 Java JDBC THIN 드라이버고, 다른 하나는 OCI기반의 드라이버라고 한다.

-. username/password은 option이다. [ ]안에 있는 정보는 반드시 명기할 필요는 없다는 뜻이다.

-. :port 번호도 option이다. 다만 Oracle의 listener port인 1521을 사용하지 않을 경우는 이 값을 명기해 줘야 된다. 예를 들어서 jdbc:oracle:thin:hr/hr@//localhost:1522

-. localhost는 Oracle DB가 설치되어 있는 서버의 IP인데 위 경우는 로컬에 설치되어 있다는 뜻이다.

-. 1521 은 오라클 listener의 포트번호이다.

-. /XE는 Oracle database client의 고유한 service name이다. 디폴트로 XE를 사용하므로 이 정보도 option이다. 이에 대한 설정 정보는 Oracle이 설치된 폴더 아래의 app\oracle\product\11.2.0\server\network\ADMIN\listener.ora 파일에 다음과 같이 표시되어 있다.

DEFAULT_SERVICE_LISTENER = (XE)




java.lang.IllegalArgumentException: Control character in cookie value or attribute.


위 에러는 JSP의 쿠키(cookie) 설정에 한글을 사용할 경우 발생하는 에러이다.

다음과 같은 JSP 코드가 있다고 가정하자.


<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">

<title>쿠키 설정</title>

</head>

<body>

<%

Cookie c = new Cookie("MemberID", "12345");

c.setMaxAge(60*60);

c.setComment("회원 ID");

response.addCookie(c);

%>

<p/>

<a href="GetCookie.jsp">쿠키 확인하기</a>

</body>

</html>


위 코드를 실행하면 


JSP java.lang.IllegalArgumentException: Control character in cookie value or attribute.라는 에러가 발생한다.

에러가 발생하는 위치는 한글을 사용한 

c.setComment("회원 ID")에서 에러가 발생한다.


해결할려면 한글을 utf-8로 인코딩한 값을 set하거나 Base64로 인코딩한 값을 set하면 된다. 

물론 쿠키를 받는 곳에서 동일한 인코딩 값으로 받아야 할 것이다.




인터페이스나 혹은 추상클래스에 있는 추상메소드의 목적

추상메소드에 대해 제대로 이해하기가 쉽지는 않는듯 하다.

추상메소드와 관련된 일반적인 '지식'에 해당되는 내용들은 얼마든지 있다.

그러나 이것이 어디에 쓰기위해 존재하는지에 대해서 명확한 정립이 되어있지 않으면 남들이 만들어 놓은 추상메소드를 코딩은 하지만 정작 내가 클래스를 만들면서 추상 메소드가 가진 목적을 발휘하는 그런 클래스를 디자인하고 만들어 쓰는데까지는 가지 못하는 것을 보게된다.

오늘은 추상 메소드(abstract method)가 존재하는 목적이 뭔지에 대해 뿌리를 캐보고자 한다.


가령 예를 들어서 우리가 어떤 디바이스를 켜는(power on) 행위(method)를 한번 생각해 보자.

power on에는 다양한 종류가 있을 것이다.

PC를 켜거나(Power On), 스마트폰을 켜거나, TV를 켜거나, ... 이럴 때 켤때마다 첫번째 초기 화면으로 그 제품을 만든 회사의 로고 이미지가 뜨도록 강제하고 싶을 경우가 있을 것이다.

PC를 켤때 삼성에서 만들었으면 삼성 로고가 뜨고 LG에서 만들었으면 LG 로그가 뜨고... 스마트폰도 마찬가지로...

이와같이 Power On 할때 초기 화면에 제조사 로고를 뜨도록 강제하고 싶을 경우 이때 이 목적을 위해서 존재하는 것이 추상 메소드(abstract method)이다.


이것을 클래스로 만들어 PowerOn이라는 클래스로 만들어보자. 

이때 PowerOn을 상속받는 하위 클래스들에서는 power on할 때(켤 때) 반드시 제조사의 로고 이미지를 뜨도록 강제하고자 하면 그에 해당하는 기능을 추상 메소드로 만들어 두면 하위 클래스에서는 반드시 로고 이미지가 뜨는 기능(method)을 만들어야만 되도록 되어 있다. 그렇지 않으면 컴파일 단계에서 에러를 발생시킨다. 따라서 그것을 상속 받는 하위 클래스에서는 무조건 로고 이미지 뜨는 기능을 구현해야만되고 이것은 하위 클래스들은 이 면에서 동일한 공통성을 띄게 강제하게 되는 결과가 된다.

말하자면 사용자들에게 동일한 인터페이스를 제공해 주게 되는 결과를 창출하게 된다.

이런 목적으로 존재하는 것인 추상 메소드이다.

예제 코드를 만들어 보자.


abstract class PowerOn

{

//하위 클래스들은 무조건 로고를 띄우는 기능을 만들도록 하고 싶다.

//그럴 경우 로고를 띄우는 메소드를 추상메소드로 만들면 된다.

abstract void showLogo(); 


public String getName() {

...

return name;

}

}



class SamsungPhone extends PowerOn

{

public void showLogo() {

//여기서 삼성 로그 띄우게

}

}


class LGPC extends PowerOn

{

public void showLogo() {

//여기서 LG 로그 띄우게

}

}


그래서 결론적으로 interface나 abstract class에 있는 abstract method의 목적은 어떤 특정 기능을(메소드를) 하위 클래스에서 반드시 만들도록 강제하고자 할때 사용하는 것이다.


그런 점에서 interface라는 것의 존재 목적이 보이는 것이다.

interface는 interface가 가지고 있는 모든 메소드는 전부 abstract 메소드이다.

추상 메소드(abstract 메소드)의 목적은 하위 클래스에 특정 기능을 반드시 만들도록 강제하고자 하는 것이 그 목적이다.

그로 인해 창출되는 결과(효과)는 하위 클래스들은 모두가 특정 기능(메소드)이 다 공통적으로 존재하게 된다는 점이다. 따라서 사용자는 어떤 하위 클래스를 사용하더라도 동일한 사용자 인터페이스를 경험하게 되는 것이다.


따라서 abstract 클래스와 유사하게 interface는 그 이름 그대로 이 interface를 상속받는(구현하는 implements하는) 하위 클래스들은 모두가 공통된 기능들을 갖추게 된다. 즉 interface에 있는 메소드들을 모든 하위 클래스들은 모두다 그 기능을(그 메소드를) 만들어야 하므로 사용자는 특정 interface를 상속받은(implements한) 모든 하위 클래스들에서는 동일한 사용자 인터페이스를 경험하게될 것이다.

이것이 interface가 노리는 목적이다.





BluetoothAdapter 클래스의 enable()라는 메소드를 통해서 Bluetooth를 강제적으로 활성화 할수 있으나

사용자로 하여금 선택할 수 있도록 하는 것이 더 바람직하다.


Google의 Android API Reference에서도 public boolean enable () 메소드에 대한 설명 가운데는

다음과 같이 사용자의 명백한 행동 없이

강제적으로 Bluetooth를 활성화시키지 말라고 얘기하고 있다.


Turn on the local Bluetooth adapter—do not use without explicit user action to turn on Bluetooth.


이때 Bluetooth를 활성화 하는 방법으로 Intent를 통해서 안드로이드 시스템에게 요청해서 

안드로이드 시스템이 사용자에게 다이얼로그 창을 띄워서 사용자가 선택하게 하고

사용자가 Bluetooth를 활성화하도록 선택을 하면 안드로이드 시스템이 Bluetooth를 

활성화 시키도록 하는 방법이 있다.

이때 BluetoothAdapter.ACTION_REQUEST_ENABLE라는 action을 Intent를 통해서

안드로이드 시스템에게 요청을 하면 된다.


Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

startActivity(enableBtIntent)라고 해도 되나 사용자가 어떤 선택을 했느냐에 따라서

그에 맞는 어떤 행동을 해야할 필요가 있기때문에 startActivityForResult()를 사용했다.

사용자의 선택 여부를 통보받는 곳이 protected void onActivityResult() 메소드를 통해서이다.


ENABLE_BT가 전역변수를 다음과 같이 선언되어 있다고 할 때

private static final int ENABLE_BT = 1;


아래는 안드로이드 시스템에게 Bluetooth 활성화 여부를 사용자에게 묻고

그 결과에 따라 활성화를 하도록 하는 코드이다.


startActivityForResult(enableBtIntent, ENABLE_BT);


사용자의 선택결과를 통보 받기 위해서는 onActivityResult()를 이용하면 된다.


@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data){

if (requestCode == ENABLE_BT  

&& resultCode == Activity.RESULT_CANCELED){

Toast.makeText(this, "취소 했습니다", 1).show();

                finish();

} else if (requestCode == ENABLE_BT 

&& resultCode == Activity.RESULT_OK){

Toast.makeText(this, "블루투스를 활성화합니다.", 1).show();

  }

}




PHP에서 2차원 배열의 내용을 출력하는 편리한 방법.


PHP에서 2차원 배열 전체를 출력하고자 할때 

list()함수와 each()함수를 이용하면 쉽게 구현할 수 있다.



<?php

$kkk = array(

        array('TIR', 'Tires', 100),

      array('OIL', 'Oil', 10),

      array('SPK', 'Spark Plugs', 4),

      array('ABC', 'Alphabet', 50)

          );


for($i=0; $i<4; $i++) {

while(list($k, $v) = each($kkk[$i])) {

echo $k." => ".$v."<br>";

}

echo "<br/>";

}

?>


each()함수는 배열(여기서는 $kkk)의 처음부터 차례대로 하나씩 key-value의 쌍으로 반환하다가 끝에 도달하면 자동으로 멈춘다.

list()함수는 key-value의 쌍을 2개의 변수(여기서는 $k와 $v)에 나누어 담는 역할을 한다.


위의 코드를 실행하면 아래와 같이 출력된다.


0 => TIR

1 => Tires

2 => 100


0 => OIL

1 => Oil

2 => 10


0 => SPK

1 => Spark Plugs

2 => 4


0 => ABC

1 => Alphabet

2 => 50





Android strings.xml에 HTML 코드 넣기

의료기 개발을 하면서 측정 결과를 공유하기 위해 

XML 형태로 전송하거나 

HTML 형태로 전송하거나 

혹은 PDF로 전송하는 등 다양한 형태의 파일로 

공유하는 작업을 하는 중에 

HTML형태의 파일로 저장하는 작업을 하면서 소스 코드 상에서 복잡한 HTML 코드를 집어 넣기에는 뭐시기해서 strings.xml을 이용하기 했다.

근데 문제는...


Android의 strings.xml에 HTML 코드를 그대로 넣으면 컴파일 단계에서 에러가 발생한다.


<string name="HtmlCSS">

<!DOCTYPE html>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

<title>Meditab Results</title>

<style type="text/css">

body {

font-family: Arial, Verdana, sans-serif;

font-size: 90%;

color: #666;

background-color: #f8f8f8;}

table {

border-spacing: 0px; }

... 이하 생략 ...


이 문제를 해결할려면 다음과 같이 바꿔 주어야 된다.


   &lt;!DOCTYPE html&gt;

&lt;html&gt;

&lt;head&gt;

      &lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"&gt;

...이하 생략...


보통 번거로운일이 아니다. ;;;

이런 문제를 한방에 해결할수 있는 방법이 있다. 다음과 같이


<![CDATA[

  이 안에 HTML 코드를 있는 그대로 넣어주면 해결된다.

]]>


이때 string 항목에 속성을 하나 추가해 주어야 하는데 formatted="false"이다.

아래는 전체 예제이다.


<string name="HtmlCSS" formatted="false">

   <![CDATA[

   <!DOCTYPE html>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

<title>Meditab Results</title>

<style type="text/css">

body {

font-family: Arial, Verdana, sans-serif;

font-size: 90%;

color: #666;

background-color: #f8f8f8;}

table {

border-spacing: 0px; }

th, td {

padding: 5px 30px 5px 10px;

border-spacing: 0px;

font-size: 90%;

margin: 0px;

}

th, td {

text-align: left;

background-color: #e0e9f0;

border-top: 1px solid #f1f8fe;

border-bottom: 1px solid #cbd2d8;

border-right: 1px solid #cbd2d8;}

tr.head th {

color: #fff;

background-color: #90b4d6;

border-bottom: 2px solid #547ca0;

border-right: 1px solid #749abe;

border-top: 1px solid #90b4d6;

text-align: center;

text-shadow: -1px -1px 1px #666666;

letter-spacing: 0.15em;}

td {

text-shadow: 1px 1px 1px #ffffff;

}

tr.even td, tr.even th {

background-color: #e8eff5;}

tr.head th:first-child {

-webkit-border-top-left-radius: 8px;

-moz-border-radius-topleft: 8px;

border-top-left-radius: 8px;}

tr.head th:last-child {

-webkit-border-top-right-radius: 8px;

-moz-border-radius-topright: 8px;

border-top-right-radius: 8px;}

fieldset {

width: 310px;

margin-top: 20px;

border: 1px solid #d6d6d6;

background-color: #ffffff;

line-height: 1.6em;}

legend {

font-style: italic;

color: #666666;}

.title {

float: left;

width: 160px;

clear: left;}

.submit {

width: 310px;

text-align: right;}

.results {

float: left;

}

</style>

</head>

<body>

<h1>Meditab Test Results</h1>

<h2>&nbsp;</h2>

<h2>개인정보 </h2>

<table>

<tr class="head">

<th>이름</th>

<th>측정일시</th>

<th>생년월일</th>

<th>성별</th>

<th>E-mail</th>

<th>진료담당</th>

</tr>

<tr> 

<th>홍길동</th>

<td>2016. 3. 5</td>

<td>1978. 5. 17</td>

<td>남</td>

<td>aslsd@naver.com</td>

<td>Dr. Park</td>

</tr>

</table>

<p />

<h2>&nbsp;</h2>

<h2>측정결과</h2>

<div >

<table class="results"> 

<tr class="head">

<th>ECG(심전도)</th>

<th>측정결과</th>

</tr>

<tr>

<td>Heart Rate</td>

<td>84</td>

</tr>

<tr>

<td>Respiratory Rate</td>

<td>19</td>

</tr>

<tr>

<td>ST Level(mV)</td>

<td>18</td>

</tr>

<tr>

<td>Arrythmia</td>

<td>Normal</td>

</tr>

</table>

<p />

<table class="results differ" > 

<tr class="head">

<th>NIBP(혈압)</th>

<th>측정결과</th>

</tr>

<tr>

<td>Systolic</td>

<td>120</td>

</tr>

<tr>

<td>Diastolic</td>

<td>84</td>

</tr>

<tr>

<td>Mean</td>

<td>96</td>

</tr>

<tr>

<td>&nbsp;</td>

<td>&nbsp;</td>

</tr>

</table>

<p />

<table class="results"> <!-- SPO2 -->

<tr class="head">

<th>SPO2(혈중 산소포화도)</th>

<th>측정결과</th>

</tr>

<tr>

<td>Saturation Value</td>

<td>100</td>

</tr>

<tr>

<td>Pulse Rate</td>

<td>84</td>

</tr>

<tr>

<td>&nbsp;</td>

<td>&nbsp;</td>

</tr>

<tr>

<td>&nbsp;</td>

<td>&nbsp;</td>

</tr>

</table>

<p />

<table class="results differ"> <!-- Temp -->

<tr class="head">

<th>Temp(체온)</th>

<th>측정결과</th>

</tr>

<tr>

<td>Temperature</td>

<td>36.3</td>


</tr>

<tr>

<td>&nbsp;</td>

<td>&nbsp;</td>

</tr>

<tr>

<td>&nbsp;</td>

<td>&nbsp;</td>

</tr>

<tr>

<td>&nbsp;</td>

<td>&nbsp;</td>

</tr>

</table>

</div>

<p/>

</body>

</html>

   ]]>

</string>





구글이 제공하는 안드로이드의 

Material design incon들이 

나름 산뜻한 느낌을 주는 디자인들이다.

이런 아이콘들을 앱에 사용하고자 한다면 

다음 사이트에서 해당 아이콘들을 각각 다운로드 받을수 있다.


https://material.io/tools/icons/?style=baseline



이 중에서 특정 아이콘을 다운로드 받고자한다면 해당 아이콘을 클릭하면 다음과 같은 다운로드 선택 창이 하단에 보이게 된다.




위의 이미지에서 파란색 띠가 보이고 원하는 것을 선택하면 된다. 

선택할 수 있는 내용은 


 -. 이미지 크기(위의 경우는 23dp. 18dp, 24dp, 36dp, 48dp의 4종류가 있다)

 -. 이미 색상(black, white)

 -. 파일의 종류(svg, png형태)


예를들어서 Dark Action Bar의 경우는 balck 아이콘을 사용하면 아이콘이 보이지 않을 것이다. 따라서 이럴 경우는 white를 체크해서 다운 받으면 된다.

다운 받는 이미지 파일의 형태도 svg와 png 형태를 선택할 수 있다.






+ Recent posts