반응형
반응형

#안드로이드 스크롤뷰 사용법 (Android scrollview)



// 스크롤 - 스크롤 처리에 대한 부분

listview.setOnScrollListener(new AbsListView.OnScrollListener() {

    @Override

    public void onScrollStateChanged(AbsListView absListView, int i) {

        // 상태에 대한 콜백 메소드

    }

    @Override

    public void onScroll(AbsListView absListView, int i, int i1, int i2) {

        // 스크롤 행위에 대한 콜백 메소드


        // 데이타가 정상적으로 다 보여졌을 때

        if (absListView.isShown()) {

            // 마지막 아이템까지 모두 보았을 경우, 페이지 추가 로드

            if(totalItemCount != 0 && (firstVisibleItem+visibleItemCount) == totalItemCount && lastitemVisibleFlag == false) {

                try {

                    // 다음 페이지 로드하는 비즈니스 로직 처리

                } catch (IOException e) {

                    e.printStackTrace();

                }

            }

        }

    }

});


반응형

#안드로이드 viewHolder 구현하기 https://developer.android.com/training/improving-layouts/smooth-scrolling.html#ViewHolder



static class ViewHolder {

TextView text;

TextView timestamp;

ImageView icon;

ProgressBar progress;

int position;

}


ViewHolder holder = new ViewHolder();

holder.icon = (ImageView) convertView.findViewById(R.id.listitem_image);

holder.text = (TextView) convertView.findViewById(R.id.listitem_text);

holder.timestamp = (TextView) convertView.findViewById(R.id.listitem_timestamp);

holder.progress = (ProgressBar) convertView.findViewById(R.id.progress_spinner);

convertView.setTag(holder);



적용전)

.......................

    /**

     * 어뎁터의 뷰를 구현하는 함수

     * @param position -- 행의 index를 의미

     * @param convertView -- 행 전체를 나타내는 뷰를 의미

     * @param parent -- 어댑터를 가지고 있는 부모의 뷰를 의미

     * @return

     */

    @Override

    public View getView(final int position, View convertView, ViewGroup parent) {

        final Context context = parent.getContext();

        View v = convertView;

        PersonViewHolder viewHolder;

        // getView에서 넘어오는 convertView는 이전에 그려졌던 view를 넘기는데요.

        // 한번도 inflate되지 않은 view라면 null로 전달되는 경우가 있으니 반드시 null체크는 해야합니다.

        if (v == null) {

            Log.e("Toggle Track:", "=========== 새로 그려지는 중입니다. ===========");

            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

           v = inflater.inflate(R.layout.activity_assem_item, parent, false);

        }// 캐시된 뷰가 있을 경우 저장된 뷰홀더를 사용한다

        else

        {

            v = (PersonViewHolder) convertView.getTag();

        }

        // Data Set(assemblyItemList)에서 position에 위치한 데이터 획득

        final AssemBean listViewItem = assemblyItemList.get(position);

        // 화면에 표시될 View(Layout이 inflate된)으로부터 위젯에 대한 데이터 획득

        ImageView imgView = (ImageView) v.findViewById(R.id.assem_empImg);

        TextView empNmView = (TextView) v.findViewById(R.id.assem_empNm);

        TextView origNmView = (TextView) v.findViewById(R.id.assem_origNm);

        ToggleButton favoriteBtn = (ToggleButton) v.findViewById(R.id.favorite); // 즐겨찾기 추가

        final TextView colorView = (TextView) v.findViewById(R.id.color); // 정당 색깔


        // 각 위젯에 데이터 반영

        Picasso.with(context).load(listViewItem.getJpgLink()).into(imgView);

        empNmView.setText(listViewItem.getEmpNm());

        origNmView.setText(listViewItem.getOrigNm());

        // 정당 색깔 구분

        colorView.setBackgroundColor(Color.rgb(128, 128, 128));

        if(listViewItem.getEmpNm().contains("강")) {

            colorView.setBackgroundColor(Color.rgb(255, 0, 0));

        }

        // 즐겨찾기 이미지 설정

        favoriteBtn.setBackgroundResource(R.drawable.imgbtn_defalut);

        if(listViewItem.getFavorite()){

            favoriteBtn.setBackgroundResource(R.drawable.imgbtn_focused);

        }


        .......................

        return v;

    }}


적용후)


..................


    /**
     * 어뎁터의 뷰를 구현하는 함수
     * @param position      -- 행의 index 의미
     * @param convertView   -- 전체를 나타내는 뷰를 의미
     * @param parent         -- 어댑터를 가지고 있는 부모의 뷰를 의미
     * @return
     */
    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {


        final Context context = parent.getContext();

        View v = convertView;

        final ViewHolder viewHolder;


        // getView에서 넘어오는 convertView 이전에 그려졌던 view 넘기는데요.
        // 한번도 inflate되지 않은 view라면 null 전달되는 경우가 있으니 반드시 null체크는 해야합니다.
        if (v == null) {

            Log.e("Toggle Track:", "=========== 새로 그려지는 중입니다===========");

            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            v = inflater.inflate(R.layout.activity_assem_item, parent, false);


            // 화면에 표시될 View(Layout inflate)으로부터 위젯에 대한 데이터 획득

            viewHolder = new ViewHolder();

            viewHolder.imgView = (ImageView) v.findViewById(R.id.assem_empImg);

            viewHolder.empNmView = (TextView) v.findViewById(R.id.assem_empNm);

            viewHolder.origNmView = (TextView) v.findViewById(R.id.assem_origNm);

            viewHolder.favoriteBtn = (ToggleButton) v.findViewById(R.id.favorite);

            viewHolder.colorView = (TextView) v.findViewById(R.id.color);

            v.setTag(viewHolder);

        }

        // 캐시된 뷰가 있을 경우 저장된 뷰홀더를 사용

        else{

            viewHolder = (ViewHolder) v.getTag();

        }


        // Data Set(assemblyItemList)에서 position 위치한 데이터 획득

        final AssemBean listViewItem = assemblyItemList.get(position);

        if(listViewItem != null){


            // 위젯에 데이터 반영
            Picasso.with(context).load(listViewItem.getJpgLink()).into(viewHolder.imgView);

            viewHolder.empNmView.setText(listViewItem.getEmpNm());

            viewHolder.origNmView.setText(listViewItem.getOrigNm());


            // 정당 색깔 구분
            viewHolder.colorView.setBackgroundColor(Color.rgb(128, 128, 128));

            if(listViewItem.getEmpNm().contains("")) {

                viewHolder.colorView.setBackgroundColor(Color.rgb(255, 0, 0));

            }


            // 즐겨찾기 이미지 설정
            viewHolder.favoriteBtn.setBackgroundResource(R.drawable.imgbtn_defalut);

            if(listViewItem.getFavorite()){

                viewHolder.favoriteBtn.setBackgroundResource(R.drawable.imgbtn_focused);

            }


            ....................


        return v;

    }


    public class ViewHolder

    {

        public int number;

        ImageView imgView;

        TextView empNmView;

        TextView origNmView;

        ToggleButton favoriteBtn;

        TextView colorView;

    }

}



참고 링크


반응형

리스트뷰 내의 아이템의 view 조합이

  1. 리스트뷰 + 아이템 내의 객체가 버튼(Button)을 포함할 때
  2. 리스트뷰 + 아이템 내의 객체가 체크박스(CheckBox)를 포함할 때
  3. 리스트뷰 + 아이템 내의 객체가 이미지 버튼(ImageButton)을 포함할 때

위의 3가지 경우에서는 아이템에서 포커스(Focus)를 가져가기 때문에 클릭이 먹히지 않는다. 



해결방법

1번과 2번의 경우) xml 파일안에서 해당 객체에 속성 추가

android:focusable="true"        -- 포커스를 주고 싶을 경우, true 그렇지 않을 경우 false 처리

android:clickable="true"        

android:focusableInTouchMode="true"


3번의 경우) java 소스 안에서 해당 객체 옵션 추가

(이미지 버튼 객체).requestFocus();

(이미지 버튼 객체).setFocusable(boolean값);


커스텀 리스트뷰에서 아이템을 클릭시, 상세화면으로 넘어가고!

버튼을 클릭시 즐겨찾기가 되게 하고 싶어서 focusable를 true로 모두 주고 나서 문제 해결

<ToggleButton

    android:id="@+id/favorite"

    android:layout_height="wrap_content"

    android:layout_width="wrap_content"

    android:layout_weight="0.3"

    android:src="@drawable/favorite_stat"

    android:focusable="true"

    android:clickable="true"

    android:focusableInTouchMode="true"/>



참고 링크

  • http://jwandroid.tistory.com/218


반응형

#ImageButton : https://developer.android.com/reference/android/widget/ImageButton.html



1) java 소스 

// button1 클릭 시 TextView(textView1)의 내용 변경.

ImageButton button1 = (ImageButton) v.findViewById(R.id.favorite);

button1.setBackgroundResource(R.drawable.imgbtn_defalut);

if(listViewItem.getFavorite()){

button1.setBackgroundResource(R.drawable.imgbtn_focused);

}

button1.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

Log.v("=========== 클릭해져여","클릭요 ==============");

}

});


2) xml 소스

<ImageButton

android:id="@+id/favorite"

android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="0dp" android:src="@drawable/favorite_stat"/>



반응형

#안드로이드 액티비티간의 데이터 전달 (intent 사용법) - 1 : 
https://developer.android.com/reference/android/content/Intent.html


인텐트란, Activity를 띄우는 과정에서 인텐트(Intent)라는 것을 생성하고 인텐트의 파라미터로 액티비티 클래스 객체를 전달하여 새로운 액티비티를 띄울 수 있다.


listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
view.setFocusable(false);

Intent intent = new Intent(AssemblyListActivity.this, AssemblyDetailActivity.class);
intent.putExtra("numOfRows",20); // 한페이지 결과수
intent.putExtra("pageNo",PAGE); // 페이지
intent.putExtra("dept_cd",searchList.get(position).getDeptCd()); // 부서코드
intent.putExtra("num",searchList.get(position).getNum()); // 국회의원 번호
intent.putExtra("jpgLink",searchList.get(position).getJpgLink()); // 사진
intent.putExtra("empNm",searchList.get(position).getEmpNm()); // 국회의원 이름
startActivity(intent);
}

});


@Override

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_assem_detail);

// 넘어온 변수 받아오기
Intent intent = getIntent();
int numOfRows = intent.getIntExtra("numOfRows", 20);
int pageNo = intent.getIntExtra("pageNo", 1);
String dep_cd = intent.getStringExtra("dept_cd");
String num = intent.getStringExtra("num");
String jpgLink = intent.getStringExtra("jpgLink");


1) 데이터 전달하기

Intent intent = new Intent(현재Activity명.this, 전달해줄Activity명.class);

intent.putExtra("전달할 데이터명",); // 한페이지 결과수

startActivity(intent); // 전달 


2) 데이터 받기

Intent intent = getIntent();

String dep_cd = intent.getStringExtra("가져올 데이터명");




*Bean 객체 intent 전달 방법


1) Intent로 전달할 객체를 Serializable 인터페이스 상속받아주기 

package com.example.n3815.new_app.common.bean;

import android.graphics.drawable.Drawable;

import com.example.n3815.new_app.common.SearchCommon;

import org.simpleframework.xml.Element;

import org.simpleframework.xml.Root;

import java.io.Serializable;

/**

 * Created by N3815 on 2016-12-27.

 * 국회의원 기본 정보 pojo 객체

 */

@Root(name = "item")

public class AssemBean implements Serializable{

    @Element(name = "deptCd", required = false)

    private String deptCd; // 부서코드

    @Element(name="num", required = false)

    private String num; // 식별코드

    @Element(name="empNm", required = false)

    private String empNm; // 한글이름

      ...................

}


2) Serializable 인터페이스를 상속받은 객체를 intent로 전달하기

ArrayList<AssemBean> assemblyList new ArrayList<AssemBean>(); // 전체 국회의원의 정보를 담는 객체

assemblyList.add(Object);

Intent intent = new Intent(LoadingActivity.this, AssemblyListActivity.class);

intent.putExtra("aseem", assemblyList); // 전달받은 객체 전달 startActivity(intent); // 화면에 뿌리기


3) Intent로 전달받은 객체 가져오기

ArrayList<AssemBean> assemblyList = new ArrayList<AssemBean>(); // 전체 국회의원의 정보를 담는 객체


// intent 받아온 Array 정보 가져오기
assemblyList = (ArrayList<AssemBean>) getIntent().getSerializableExtra("assem");




*부모 Activity 또는 타 Activity의 메소드 실행시키기

// 변경된 정보값을 다시 원본 배열에게 알리기

((AssemblyListActivity) context).changeItemInfo(selectedAssem);

  • ((전달/실행시키려는 Activity명) context).호출할 메소드명(전달값);


* 여러 Activity를 요청 코드로 분류하여 요청하기 

public static final int REQ_CODE_ANOTHER_ACTIVITY = 1001;


// 1. 새로운 액티비티 요청시 요청코드와 함께 액티비티를 띄우기

public void onButton1Clicked(View v){

Intent intent = new Intent(getApplicationContext(), AnotherActivity.class);

startActivityForResult(intent, REQ_CODE_ANOTHER_ACTIVITY);

}


// 2. 요청한 액티비티 전달이 잘 되었는지 확인 

public void onActivityResult(int requestCode, int resultCode, Intent intet){

super.onAcitivyResult(requestCode, resultCode, intent);


if(requestCode == REQ_CODE_ANOTHER_ACTIVITY){

// 1번에서 띄운 액티비티의 요청 : onActivityResult가 실행됨

}


if(reslutCode == RESULT_OK){

// 응답으로 전달된 내용

}

}




* Intent의 Action 사용법

Intent intent = new (Itent.ACTION_DIAL, uri,parse("01012341234")); // new (Intent Action, 데이터)

startActivity(intent); // intent 메소드(intent);


* Intent Action 종류

 Action name

 설명

 ACTION_MAIN

 

 ACTION_ATTACH_DATA

 

 ACTION_PICK

 

 ACTION_GET_CONTENT

 

 ACTION_CALL

 전화 걸기 

 ACTIOIN_SENDTO

 

 ACTION_RUN

 

 ACTION_PICK_ACTIVITY

 

 ACTION_WEB_SEARCH

 
 ACTION_VIEW 
 ACTION_EDIT 
 ACTION_CHOOSER 
 ACTION_DIAL 
 ACTION_SEND 

 ACTION_SYNC

 

 ACTION_SEARCH

 
 ACTION_ANSWER 
 ACTION_DELETE 
 ACTION_FACTORY_TEST 


* Intent 메소드 종류

  1. startActivity() : 액티비티를 띄울 때 사용
  2. startService() : 서비스를 시작 시킬 때 사용
  3. broadcastIntent() : 브로드캐스팅을 수행할 때 사용

어지는 링크


반응형

#LinearLayout : https://developer.android.com/reference/android/widget/LinearLayout.html

  • Relative와 다르게 LinearLayout은 각 Obj들이 서로 중첩되지 않는다.
  • 특정 Obj기준으로 View Layout을 쌓는 느낌이다. 


1. 프로필 사진 레이아웃

<!-- 1번 레이아웃 -->

<LinearLayout
android:layout_height="60dp"         // 높이(세로)
android:layout_width="60dp"          // 길이(가로)
android:layout_marginLeft="10dp"     // 왼쪽 마진
android:orientation="vertical">      // 정렬 여부


<ImageView
android:id="@+id/assem_empImg"     // ImageView 아이디
android:layout_width="60dp"        // 길이(가로)
android:layout_height="60dp"/>     // 높이(세로)

</LinearLayout>

2~4. 상세정보 레이아웃

<!-- 내용 -->
<LinearLayout
android:layout_width="200dp"    
android:layout_height="60dp"
android:layout_marginLeft="10dp"
android:layout_toRightOf="@+id/assem_empImg"     // 1번 프로필 사진(assem_empImg) 오른쪽에 정렬

android:orientation="vertical"                    // 세로 정렬!
android:weightSum="1">        // 하위 뷰에 대해서 가로에 대해서 상대적인 비율을 주기 위한 옵션

<!-- 2, 3번 레이아웃 -->
<LinearLayout
android:layout_width="200dp"
android:layout_height="25dp"
android:layout_toRightOf="@+id/assem_empImg"    // assem_empImg 오른쪽에 정렬
android:orientation="horizontal"       // 2번 3번 obj를 붙이기 위한 가로 정렬
android:weightSum="1">
            
<TextView
android:id="@+id/assem_empNm"      // textView의 ID 설정
android:layout_height="25dp"    
android:layout_width="50dp"
android:layout_gravity="top"       // 정렬은 LinearLayout의 top에 붙이기
android:textSize="12sp"            // 폰트 사이즈 12sp
android:textStyle="normal|bold"/> // 텍스트 스타일 : 굵게

<TextView
android:id="@+id/assem_dang"       // textView의 ID 설정
android:layout_width="140dp"
android:layout_height="25dp"
android:layout_toRightOf="@+id/assem_empNm" // assem_empNM의 오른쪽에 정렬
android:layout_gravity="top"           // 정렬은 LinearLayout의 top에 붙이기
android:textSize="12sp"                
android:textStyle="normal|bold"
android:layout_marginLeft="10dp" />       
</LinearLayout>

         <!-- 4번 레이아웃 -->
<TextView
android:id="@+id/assem_origNm"
android:layout_weight="0.22" // 하위 뷰에 대해서 가로에 대해서 상대적인 비율을 주기 위한 옵션
android:layout_height="25dp"
android:layout_width="200dp"
android:layout_gravity="bottom"    // LinearLayout의 바닥에 정렬

android:textSize="12sp"
android:layout_marginTop="10dp"
android:textStyle="normal|bold"
android:textAlignment="center" />        // 텍스트 정렬은 가운데

</LinearLayout>

5. 즐겨찾기 레이아웃

  <!-- 5번 레이아웃 -->

<LinearLayout
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginLeft="10dp"
android:orientation="vertical"
android:weightSum="1"
android:layout_marginRight="10dp">

<ToggleButton
android:id="@+id/favorite"
android:layout_width="60dp"
android:layout_height="60dp"
android:textOff="OFF"              // 꺼졌을 때, 텍스트 정의
android:textOn="ON"                // 켜졌을 때, 텍스트 정의
android:src="@drawable/favorite_stat"/>    // 토글 버튼의 style 지정

</LinearLayout>


참고 링크


반응형

# Layout Inflater : https://developer.android.com/reference/android/view/LayoutInflater.html

안드로이드에서는 화면을 구성하는 방법으로  xml 레이아웃을 사용하는데, 이 xml 레이아웃 파일의 내용은 애플리케이션이 실행될 때 메모리로 로딩되어서 객체화 된다. xml 레이아웃에 정의된 내용을 메모리 상에 객체화되는 과정을 '인플레이션(inflation)' 이라고 한다. 

즉, xml 레이아웃 파일은 프로젝트가 빌드되는 시점에 이진 파일로 컴파일되어 애플리케이션에 포함되긴 하지만, 

실제로 실행시점이 되어서야 메모리에 로딩되어 객체화가 된다는 말이다.


예제 1)

onCreate(bundle saveInstanceState){

super.onCreate(saveInstanceState);


// 버튼 호출

setContentView(R.layout.activity_main); 

}

setContentView전에 button을 호출하게 된다면 당연히 오류가 난다. 

메모리상에 객체화 (로드) 되지 않은 데이타를 호출하려고 했기 때문에 오류가 나면서 애플리케이션이 중지된다.


즉, setContentView() 메소드의 역할은

  1. 화면에 나타낼 뷰를 지정
  2. xml 레이아웃의 내용을 메모리상에 객체화

그렇다면, 화면 전체에 나타낼 xml 레이아웃이 아니라 전체 화면 중에서도 일부분만 차지하는 화면 구성 요소들을 xml 레이아웃에서 로딩하여서 보여줄 순 없을까? 있다. 다만, 다른 메소드를 사용해야한다.  layoutInflater 라는 클래스를 사용하여서 해야한다. (페이지 216~)


예제 2)

getSystemService(Context.LAYOUT_INFLATER_SERVICE)

이렇게 layoutInflater를 참조시킨 후에 사용이 가능하다. 


참고 링크

  • 안드로이드 앱 프로그래밍
  • 안드로이드 개발자 센터 


반응형

#액티비티 (Activity) : https://developer.android.com/reference/android/app/Activity.html





안드로이드 생명주기 사용법

public class Activity extends ApplicationContext {

     protected void onCreate(Bundle savedInstanceState);

     protected void onStart();

     protected void onRestart();

     protected void onResume();

     protected void onPause();

     protected void onStop();

     protected void onDestroy();

 }

생명주기 메소드에 대한 설명

  1. onCreate()
    • Activity  초기화 및 화면 설정
  2. onRestart()
    • App이 재시작될 때 호출되는 함수로, onStart() 직전에 호출
  3. onStart()
    • 액티비티가 사용자에게 보이기 직전에 호출
  4. onResume()
    • 사용자와 상호작용을 하기 전에 호출되는 함수
    • Activit 스택의 맨 위에 있어서 Activity가 사용자에게 보여지고, 사용자의 입력을 처리할 수 있을 때 호출
  5. onPause()
    • 다른 Activity가 호출될 때 호출된다. 
    • 데이터 저장 및 스레드 중지 등의 처리를 하기에 좋은 메소드
  6. onStop()
    • 더이상 Activity가 스택의 최상 위에 있지 않을 때 즉, 사용자에게 보이지 않게 될 때 호출
    • 메모리가 부족할 경우, onStop() 메소드가 호출되지 않을 수도 있다.
  7. onDestory()
    • Activity를 종료/소멸될 때 호출
    • finish() 메소드가 호출되거나 시스템이 메모리 확보를 위해서 액티비티 제거시 호출됨



+ Recent posts