2014. 5. 19. 15:49



쫄지마 창업스쿨을 첫강의때

이희우 대표님이 이 책을 읽고 창업 했다는 이야기를 듣고, 

호기심에 동해서 읽게 된 책.


저자인 랜디코미사는 실리콘벨리에 있는 투자자이다.

그에게 투자를 받기 위해 찾아온 한 사업가와의 미팅 후 그의 생각과 자신이 해왔던 것에 대해,

그리고 자신이 길을 걸으면서 잘못된 점 같은 것들을 짚으면서 다른 독자들에게 얘기해주고 있다.


이 책을 읽게 된 계기는 크게 두가지인데,

추천 해주신 이희우 대표님이 이 책을 밤새 읽었다고 한다.

다음 날 아침 바로 사업을 시작하게 됬다는 대표님을 보고,

지금은 조금 식어있는 나의 열정을 다시 지필 수 있지 않을까한 이유가 첫번째다.

두번째는 책 처음부분에 작가는 계란을 1m에서 땅으로 떨어뜨려야 하는데,

 깨지지 않게 떨어뜨리기 위해서는 어떻게 해야하는가라는 수수께끼가 나온다. 그게 바로 책 제목이지만.

그 답이 책에 나온다길래 그것도 보고싶었기 때문이다.

당시 나는 듣자마자 떠오르는 것은 어차피 떨어질 것인데,

그냥 후라이팬에 떨어뜨려서 구워 먹겠다였다.

답은 책에 나오니 궁금하신 분은 직접 읽어보시길 ^^;;

(그리 큰 기대는 하지마시길)


Posted by 나돌라
2014. 2. 6. 15:40

오늘은 저번에 참고했던 SlidingMenu를 이용해서,

기본적인 앱 구조를 구현 코드입니다.

예제 소스를 돌려도 실제로 제가 돌리기 위한 소스를 만들기까지는

한참 시간이 걸리기때문에 포스팅합니다.


이를 이용하기 위해서는 사전 작업이 필요한데,

안보신분은 

http://naddola.tistory.com/entry/androidSliding-Menu-%EB%A9%94%EB%89%B4-%EB%8F%8C%EB%A0%A4%EB%B3%B4%EA%B8%B0jfeinstein10%EC%98%A4%ED%94%88%EC%86%8C%EC%8A%A4

를 먼저 해보시고 오는걸 추천드립니다.


새 프로젝트를 SlidingSimpleSample로만들고,

저번에 이용했던, library를 참조합니다.


 

추가했더니 또

 Found 2 versions of android-support-v4.jar in the dependency list,

라는 경고가 뜨네요.

 이미 설명했던 것이니, 가볍게 libs폴더에 있는

android-support-v4.jar

삭제해버렷!

 

이제 필요한 자바파일입니다.

BaseActivity.java

적용시켰던 ExampleListActivity에서 수정했습니다.

package com.example.slidingsimplesample;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.ListFragment;

import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu;
import com.jeremyfeinstein.slidingmenu.lib.app.SlidingFragmentActivity;

public class BaseActivity extends SlidingFragmentActivity {

	protected ListFragment mFrag;

	public BaseActivity() {
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);


		// set the Behind View
		setBehindContentView(R.layout.menu_frame);
		if (savedInstanceState == null) {
			FragmentTransaction t = this.getSupportFragmentManager().beginTransaction();
			mFrag = new MenuListFragment();
			t.replace(R.id.menu_frame, mFrag);
			t.commit();
		} else {
			mFrag = (ListFragment)this.getSupportFragmentManager().findFragmentById(R.id.menu_frame);
		}

		// customize the SlidingMenu
		SlidingMenu sm = getSlidingMenu();
		sm.setShadowWidthRes(R.dimen.shadow_width);
		sm.setShadowDrawable(R.drawable.shadow);
		sm.setBehindOffsetRes(R.dimen.slidingmenu_offset);
		sm.setFadeDegree(0.35f);
		sm.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);

		getSupportActionBar().setDisplayHomeAsUpEnabled(true);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case android.R.id.home:
			toggle();
			return true;
		
		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getSupportMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
	

	public void fragmentReplace(int reqNewFragmentIndex) {
		 
        Fragment newFragment = null;
 
        newFragment = getFragment(reqNewFragmentIndex);
 
        final FragmentTransaction transaction = getSupportFragmentManager()
                .beginTransaction();
 
        transaction.replace(R.id.fragment_mainContainer, newFragment);
 
        getSlidingMenu().showContent();
        transaction.commit();
    }
	
	private Fragment getFragment(int idx) {
        Fragment newFragment = null;
 
        switch (idx) {
        case 0:
            newFragment = new Fragment1();
            break;
        case 1:
            newFragment = new Fragment2();
            break;
        case 2:
            newFragment = new Fragment3();
            break;
        default:
            break;
        }
 
        return newFragment;
    }
}


MainActivity.java

메인 액티비티입니다.

package com.example.slidingsimplesample;

import android.os.Bundle;
public class MainActivity extends BaseActivity{

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		fragmentReplace(0);
	}

}


MenuListFragment.java

메뉴에 있는 아이템을 실질적으로 채워주는 부분입니다.

package com.example.slidingsimplesample;
 
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

public class MenuListFragment extends ListFragment {
 
     
    public MenuListFragment(){
    }
 
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        return inflater.inflate(R.layout.list, null);
    }
 
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        SampleAdapter adapter = new SampleAdapter(getActivity());
        adapter.add(new SampleItem("Fragment1", android.R.drawable.ic_menu_search));
        adapter.add(new SampleItem("Fragment2",
                android.R.drawable.ic_menu_search));
        adapter.add(new SampleItem("Fragment3", android.R.drawable.ic_menu_search));
 
        setListAdapter(adapter);
    }
 
    private class SampleItem {
		public String tag;
		public int iconRes;

		public SampleItem(String tag, int iconRes) {
			this.tag = tag;
			this.iconRes = iconRes;
		}
	}

	public class SampleAdapter extends ArrayAdapter<SampleItem> {

		public SampleAdapter(Context context) {
			super(context, 0);
		}

		public View getView(int position, View convertView, ViewGroup parent) {
			if (convertView == null) {
				convertView = LayoutInflater.from(getContext()).inflate(
						R.layout.row, null);
			}
			ImageView icon = (ImageView) convertView
					.findViewById(R.id.row_icon);
			icon.setImageResource(getItem(position).iconRes);
			TextView title = (TextView) convertView
					.findViewById(R.id.row_title);
			title.setText(getItem(position).tag);

			return convertView;
		}
	}

 
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
         
        switch (position) {
        case 0:
            ((BaseActivity)getActivity()).fragmentReplace(0);
            break;
        case 1:
            ((BaseActivity)getActivity()).fragmentReplace(1);
            break;
 
        case 2:
            ((BaseActivity)getActivity()).fragmentReplace(2);
            break;
        }
        super.onListItemClick(l, v, position, id);
    }
}


Fragment1.java

메뉴 1입니다.

package com.example.slidingsimplesample;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class Fragment1 extends Fragment {
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View v = inflater.inflate(R.layout.fragment1, container, false);
		return v;
	}
}


Fragment2.java

메뉴 2입니다.

package com.example.slidingsimplesample;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class Fragment2 extends Fragment {
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View v = inflater.inflate(R.layout.fragment2, container, false);
		return v;
	}
}


Fragment3.java

메뉴 3입니다.

package com.example.slidingsimplesample;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class Fragment3 extends Fragment {
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View v = inflater.inflate(R.layout.fragment3, container, false);
		return v;
	}
}




xml파일입니다.

activity_main.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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <LinearLayout
        android:id="@+id/fragment_mainContainer"
        android:layout_gravity="center_horizontal"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical"
        android:gravity="center_horizontal"
         />

</RelativeLayout>


fragment1.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <TextView
        android:id="@+id/tv1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:text="fragment1"/>

</LinearLayout>


fragment2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <TextView
        android:id="@+id/tv2"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:text="fragment2"/>

</LinearLayout>


fragment3.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <TextView
        android:id="@+id/tv3"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:text="fragment3"/>

</LinearLayout>


list.xml

<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
     />


menu_frame.xml

<?xml version="1.0" encoding="utf-8"?>

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/menu_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />


row.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/row_icon"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:padding="10dp"
        android:src="@drawable/ic_launcher" />

    <TextView
        android:id="@+id/row_title"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:gravity="center_vertical"
        android:padding="10dp"
        android:text="Medium Text"
        android:textAppearance="@android:style/TextAppearance.Medium" />

</LinearLayout>


다음으로 value폴더에 있는 dimens.xml 도 변경합니다.

dimens.xml

<resources>
  <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
     <dimen name="slidingmenu_offset">60dp</dimen>
    <dimen name="list_padding">10dp</dimen>
    <dimen name="shadow_width">15dp</dimen>

    <integer name="num_cols">1</integer>
</resources>


마지막으로 그림자 효과에 대한 xml을 넣어야하는데 이친구는

drawable폴더에 넣어야됩니다.

shodow.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >

    <gradient
        android:endColor="#33000000"
        android:centerColor="#11000000"
        android:startColor="#00000000" />

</shape>


여기까지 하시고 돌려보면



다음과 같은 결과를 얻을 것입니닷!

그럼 열코딩 하시길~


밑에는 아예 세개 프로젝트를 압축해놨습니다.

SlidingSimpleSample.zip

import하시면 됩니다.


Posted by 나돌라
2014. 1. 20. 10:41

안녕하세요.

앱을 개발하다가 페이스북같은 슬라이드 메뉴를 구현하고 싶었는데,

참고할 만한 오픈소스가 jfeintsein10이라는 소스가 굉장히 유명하더군요.


그래서 참고하고 싶었는데, 예제만 돌리는데 정말 힘들었습니다.

혹여나 저같은 분들이 있을까봐 포스팅합니다.


먼저 이 예제파일을 실행하기 위해서는 두가지를 다운 받아야합니다.


1. jfeinstein10 오픈소스

우리가 사용하려고 하는 오픈소스죠.

https://github.com/jfeinstein10/SlidingMenu


2. ActionBarSherlock

저도 자세한건 모르겠으나 위의 오픈소스가 이걸 사용하더군요.

http://actionbarsherlock.com/




다운 받은 zip들은 압축을 풀어줍니다.

이제 이클립스를 키고,

[NEW] - [other] - [Android] - [Android Project from Existing Code]를 선택

압축 풀린 Slidingmenu폴더를 선택하면

이런 식으로 나올텐데요.

두개다 추가하면 됩니다. 이때 밑에 Copyprojects into workspace는 꼭 체크해주세요.

이걸 체크해야 복사해서 추가하기때문에 원본은 그대로 있습니다.


같은 방법으로 ActionBar도 추가해보면

이런 식으로 뜹니다.

이때 다른 프로젝트들은 다 필요 없으니까 첫번째 프로젝트(actionbarsherlock)만 체크하고,

나머지는 전부 풀어줍니다.

마찬가지로 Copy projects into workspace는 체크해줍니다.


자 여기까지 하셨다면 아마 이런 결과 일겁니다.


자 이제 할 일은 서로 엮어주고 고쳐주면 됩니다.

구조는 이런식입니다.

actionbarsherlock은 라이브러리화 되서 library가 참고하고,

library 또한 라이브러리화 되서 ExamplelistActivity가 참고하는 구조입니다.


 actionbarsherlock프로젝트library프로젝트properties로 들어가 Islibrary를 체크해줍니다.

(아마 되있을겁니다.)



다음, library프로젝트 Properties에서 Add버튼을 누른 후 actionbarsherlock을 추가시킵니다.


그러면 Console창에

Found 2 versions of android-support-v4.jar in the dependency list,~~~

같은 어마무시한 경고가 뜨는데 이것은 android-support-v4.jar라는 파일이 둘 다 있어서 중복된다는 소리입니다.

library프로젝트의 libs폴더에 있는 android-support-v4.jar파일을 삭제 합니다.


다음 library프로젝트의 SlidingFragmentActivity를 찾아서, 

public class SlidingFragmentActivity extends FragmentActivity implements SlidingActivityBase {

이부분을

public class SlidingFragmentActivity extends SherlockFragmentActivity implements SlidingActivityBase {

으로 바꿉니다.


그럼 아마 모든 에러는 사라질 것이고

ExampleListActivity프로젝트를 실행하면,

이 화면을 보실 수 있을 겁니다.



 ps. Unable to resolve target 'android-16' 류의 경고가 뜬다면 Properties에서 Buildtarget을 GoogleAPIs로 바꿔보세요.


다음에는 이 코드를 이용해서 실질적으로 사용하는 예제 소스를 준비하겠습니다.



Posted by 나돌라