본문 바로가기

개발/모바일

stanford CS 193A 16sp Lecture 04: Files, Stanford Library, Styles

반응형

강의 링크 : https://www.youtube.com/watch?v=PKnWgQsbwuw&t=465s


1. Files and Storage

- 안드로이드는 두 장소에서 파일을 읽어올 수 있다 : 내부/외부 저장소. 둘 다 persistent storage이며, 전원을 꺼도 데이터는 유지된다

- internal storage : Built into device

 * guaranteed to be present

 * typically smaller

 * can't be expanded to removed

 * specific and private to each app

 * wiped out when the app is uninstalled


- 내부 저장수에 파일을 넣고 싶으면? res/raw폴더



2. File and Streams

- java.io.File : 파일이나 디렉토리를 나타내는 객체 Objects that represent a file or directory

  * 메소드들 : canRead, canWrite, create, delete, exits, getName, getParent, getPath, isFile, isDirectory, lastModified, length, listFiles, mkdir, mkdirs, renameTo


- java.io.InputStream, OutputStream : 특정 소스에서 데이터가 들어오고 나가는 흐름을 나타내는 객체Stream objects represent flows of data bytes from/to a source of destination.

 * Could come from a file, network, database, memory, ..

 * Normally not directly used; they only include low-level methods for reading/writing a byte at a time from the input.

 * 바이트단위로 밖에 안되고 try/catch해야되서 불편함

 * java.util.Scanner, java.io.BufferedReader, java.io.PrintStream 등 실제 읽기/쓰기를 하는 객체의 매개변수로 많이 사용됨


3. Scanner



4. Using internal storage

- 파일을 읽고 쓸 수 있는 메소드들

getResources().openRawResource(R.raw.id) // read an input from res/raw

getFilesDir() // returns internal directory for your app

getCacheDir() // returns a "temp" directory for scrap files

openFileInput("name", mode) // opens a file for reading

openFileOutput("name", mode) // opens a file for writing

-많은 메소드들이 표준 java.io.File 객체를 반환/ 몇몇은 java.io.InputStream 또는 OutputStream 객체를 반환해서 Scanner, BufferReader, PrintStream 과 함께 쓸 수 있음



5. 단어장 프로젝트 파일에서 읽기

package com.example.han.lec3ninjaturtles;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Scanner;

public class MainActivity extends AppCompatActivity {
private HashMap<String, String> dictionary;
private ArrayList<String> list;
private ArrayAdapter<String> adapter;
private ArrayList<String> fiveDefinition;

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



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

fiveDefinition = new ArrayList<String>();

readWordsFromFile();
pickRandomWord();


}
private void readWordsFromFile(){
// read file => into list

list = new ArrayList<String>();

//res/raw에 hello.txt가 있다고 가정
Scanner sc = new Scanner(getResources().openRawResource(R.raw.words));

// sc.useDelimiter(" - "); // 이렇게 읽으면 hasNext(); 로 읽어들이면 됨
while(sc.hasNextLine()){
String line = sc.nextLine();
String wordAndDef[] = line.split(" - ");
list.add(wordAndDef[0]);
dictionary.put(wordAndDef[0], wordAndDef[1]);
}
sc.close();
}
private void pickRandomWord(){
ArrayList<String> fiveWords = new ArrayList<String>();
//shuffle word
Collections.shuffle(list);
for(int i = 0 ; i < 5; i++){
fiveWords.add(list.get(i));
}
// 하나 골라서 문제냄
final String theWord = fiveWords.get(0);
// list of matched definition

fiveDefinition.clear();
for(String word: fiveWords)
fiveDefinition.add(dictionary.get(word));
Collections.shuffle(fiveDefinition);


//listView를 위한 adapter를 만들어야 함
if(adapter==null){
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, fiveDefinition);
}else{
adapter.notifyDataSetChanged();
}
ListView listView = (ListView)findViewById(R.id.word_list);
listView.setAdapter(adapter);

TextView word = (TextView)findViewById(R.id.word);
word.setText(theWord);

// clickable하게 만들기
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
// new anonymous 어쩌고를 만들면 위에서 변수 선언할 때 final이어야 함
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
String defnClicked = fiveDefinition.get(position);
String rightAnswer = dictionary.get(theWord);
if(defnClicked.equals(rightAnswer)) {
/* Toast.makeText(this, "you got it!", Toast.LENGTH_SHORT).show();
* 지금 this는 activity 가 아님 */
Toast.makeText(MainActivity.this, "you got it!", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(MainActivity.this, "wrong!", Toast.LENGTH_SHORT).show();
}

pickRandomWord();

}
});
}

} 



6. make new file 34분

단어를 추가/수정하고 싶으면 새로운 파일을 만들어야 함. (처음에 추가한 텍스트파일은 이미 앱에 박힌 상태라서)


7. External storage

- 기기에 따라 나타나지 않을 수도 있음

- 다른 앱이나 유저들이 읽거나 쓸 수도 있음. not private to your app

- 앱을 지워도 삭제 되지 않음. 몇몇 클래스는 예외

- 앱이 기기의 외부 저장소에 읽기/쓰기가 필요하다면 AndroidManifest.xml파일에서 permission을 명시해 줘야 함.


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.han.lec3ninjaturtles">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>


...
</manifest>

 


예시코드


8. Stanford Library


-라이브러리 추가하기

http://web.stanford.edu/class/cs193a/lib/ 에서 stanford-android-lib.jar파일을 다운받은 후 app/libs에 넣음.

탐색기 위에 android를 project로 바꾸면 프로젝트 내 모든 파일을 볼 수 있음. 여기서 .jar파일을 우클릭 후 add as library

public class MainActivity extends SimpleActivity{ // extends Activity 대신에 이렇게 씀 


- 몇몇 기능
* casting 없이 find를 할 수 있음
//        ListView listView = (ListView)findViewById(R.id.word_list);
ListView listView = (ListView)find(R.id.word_list); 

* textView찾기와 setText를 한 줄에

//        TextView word = (TextView)findViewById(R.id.word);
// word.setText(theWord); findTextView(R.id.word).setText(theWord); 


*Log, Print, Toast

 

*List

 // ListView listView = (ListView)findViewById(R.id.word_list);

        ListView listView = (ListView)find(R.id.word_list);
// listView.setAdapter(adapter);

/* //listView를 위한 adapter를 만들어야 함
if(adapter==null){
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, fiveDefinition);
}else{
adapter.notifyDataSetChanged();
}*/
SimpleList.with(this)
.setItems(listView, fiveDefinition);


최종 코드

SimpleList.with().setItems() 부분이 자꾸 에러나서 그냥 어댑터로 돌렸다.

package com.example.han.lec3ninjaturtles;

import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Scanner;

import stanford.androidlib.SimpleActivity;

public class MainActivity extends SimpleActivity {
private HashMap<String, String> dictionary;
private ArrayList<String> list;
private ArrayAdapter<String> adapter;
private ArrayList<String> fiveDefinition;
private String theWord;

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

dictionary = new HashMap<String, String>();
fiveDefinition = new ArrayList<String>();

readWordsFromFile();
pickRandomWord();


}
private void readWordsFromFile(){
// read file => into list

list = new ArrayList<String>();

//res/raw에 hello.txt가 있다고 가정
Scanner sc = new Scanner(getResources().openRawResource(R.raw.words));

// sc.useDelimiter(" - "); // 이렇게 읽으면 hasNext(); 로 읽어들이면 됨
while(sc.hasNextLine()){
String line = sc.nextLine();
String wordAndDef[] = line.split(" - ");
list.add(wordAndDef[0]);
dictionary.put(wordAndDef[0], wordAndDef[1]);
}
sc.close();
}
private void pickRandomWord(){
ArrayList<String> fiveWords = new ArrayList<String>();

//shuffle word
Collections.shuffle(list);
for(int i = 0 ; i < 5; i++){
fiveWords.add(list.get(i));
}

// 하나 골라서 문제냄
theWord = fiveWords.get(0);
// TextView word = (TextView)findViewById(R.id.word);
// word.setText(theWord);
findTextView(R.id.word).setText(theWord);

// list of matched definition
fiveDefinition.clear();
for(String word: fiveWords)
fiveDefinition.add(dictionary.get(word));
Collections.shuffle(fiveDefinition);

/* // stanford library로 listView 적용하기
// 이 부분에서 자꾸 에러가 남!
ListView listView = (ListView)findViewById(R.id.word_list);
SimpleList.with(this).setItems(listView, fiveDefinition);*/

//listView를 위한 adapter를 만들어야 함
ListView listView = (ListView)find(R.id.word_list);
if(adapter==null){
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, fiveDefinition);
}else{
adapter.notifyDataSetChanged();
}
listView.setAdapter(adapter);


// listen to clicks on listview
// 리스트를 클릭하면 onItemClick 호출
listView.setOnItemClickListener(this);



// clickable하게 만들기
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
// new anonymous 어쩌고를 만들면 위에서 변수 선언할 때 final이어야 함
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
String defnClicked = fiveDefinition.get(position);
String rightAnswer = dictionary.get(theWord);
if(defnClicked.equals(rightAnswer)) {
// Toast.makeText(this, "you got it!", Toast.LENGTH_SHORT).show();
// * 지금 this는 activity 가 아님
toast("you got it!");
// Toast.makeText(MainActivity.this, "you got it!", Toast.LENGTH_SHORT).show();
}else {
toast("wrong", Toast.LENGTH_LONG);
// Toast.makeText(MainActivity.this, "wrong!", Toast.LENGTH_SHORT).show();
}

pickRandomWord();

}
});

}

// 리스트 클릭에 스탠포드 라이브러리 이용
@Override
public void onItemClick(ListView list, int index) {
String defnClicked = fiveDefinition.get(index);
String rightAnswer = dictionary.get(theWord);
if(defnClicked.equals(rightAnswer)) {
toast("you got it!");
}else {
toast("wrong", Toast.LENGTH_LONG);
}
pickRandomWord();
}

} 





9. Styles and Themes


- 색깔 정의  : 

<color>태그에 정의(hex strings로 #RRGGBB) 하고 이름을 지정 @color/name


  res/values/styles.xml

 <resources>

     <color name="orangeee">#FF0000</color>
     ...
</resources>



- res/ : resource files (주로 XML)

 * drawable/ :imgaes

 * layout/ : descriptions of GUI layout

 * menu/ : overall app menu options

 * values/ : constant values, arrays, styles (ex, styles.xml)

 * strings/ : localization data


res/values/styles.xml

 <resources>

...

<style name="MyFontStyle">
<item name="android:textColor">#FF00FF</item>
<item name="android:padding">30dp</item>
</style>

</resources>


 

 activity_main.xml

<LinearLayout ...>

<TextView
style="@style/MyFontStyle"
... />
...

</LinearLayout>



 - Themes : 여러 스타일의 집합


반응형