레이블이 android인 게시물을 표시합니다. 모든 게시물 표시
레이블이 android인 게시물을 표시합니다. 모든 게시물 표시

2022년 11월 2일 수요일

[Flutter] Dart에서 getter, setter 함수 만들기

 Dart 에서 get, set 함수를 만들수있습니다.

private 변수를 get, set 함수를 이용해서 값을 가져오거나 넣을 수 있습니다.




get 함수와 set 함수 입니다.

get함수 name을 호출하면,  _name 의 변수가 null이 아니라면, _name 의 값을,

null 이라면, empty 를 출력합니다.


set함수 name에 값을 넣어주면, 넣어준 값이, _name에 저장됩니다.


위 get, set 함수 사용 예 입니다.



이 구문의 실행 결과입니다.



set을 통해 입력한값들을 확인 할 수 있습니다.

2022년 10월 31일 월요일

[Flutter] android 릴리즈모드 빌드한 apk 를 스마트폰 설치 후, 네트워크 에러 해결방법

 Flutter 개발 하다보면, 릴리즈 모드로 빌드해서 apk 를 직접 스마트폰에 설치하는 일을 해 볼 것이다.


개발 모드 그러니까, 개발 피시에서 직접 폰에 바로 빌드를 하면, 앱에서 사용하는 네트워크동작이 잘 되는데, 

릴리즈 모드로 apk를 빌드해서 직접 스마트폰에 설치해서 실행해 보면,

로그인 페이지는 뜨지만 로그인되지 않고 네트워크오류가 발생 한다.


원인은 Internet 권한 문제 때문이다.




개발 모드에서 네트워크 연결이 잘 되는 이유는,

profile 폴더아래, AndroidManifest.xml 파일에, 이미 권한 허용 구문이 들어있기 때문이다.

<uses-permission android:name="android.permission.INTERNET"/>


이 구문이, main 폴더아래, AndroidManifest.xml 파일에 넣어 줘야한다.



해당 권한 구문을 넣으면 네트워크 오류 없이 개발모드와 동일하게 동작하는 것을 볼 수 있을 것이다.

2022년 10월 26일 수요일

[Flutter] mutable 과 immutable 에 대해서

 Dart 언어에서 뿐만 아니라, 다른 개발 언어에서도, 마찬가지로 알고 가야 할 개념인

mutable과 immutable 개념을 알아보자


mutable  : 변경가능, immutable : 변경 불가능


예를 들어, 

class Car {
int? id;
String? model;

Car({this.id, this.model});
}

void main() {
Car car = Car(id:1, model:'m1');
Car car2 = car;

print('car, id=${car.id}, model=${car.model}');

car2.model = 'm2';

print('car2, id=${car.id}, model=${car.model}');
print('car, id=${car.id}, model=${car.model}');
}

결과값

car, id=1, model=m1
car2, id=1, model=m2
car, id=1, model=m2

car2 에 car를 받아서, car2의 변수를 변경했는데, car2 의 model 변수 뿐아니라,

car의 model 변수 값도 변경되었다.

이경우, car의 주소값이 car2에게 복사 된것이므로 같은 주소값을 가지고 있기때문이다, 그래서 car 객체 변수는 mutable 한 것 이다.


car2를 다른 주소값으로 갖게하게끔 Car객체를 생성하고 싶다면,

Car car2 = car;

대신, Car car2 = Car(id:1, model:'m2'); 라고 새로 객체를 생성해주면, car와 별개의 주소값

을 갖게된다.


다른예로,

final name1 = 'David';

const name2 = 'Paul';

둘다, immutable에 해당하는 변수 이다.

값을 할당하면, 다시 변경 불가능한 변수가 되게 final과 const를 붙였기 때문이다.ㅏ

final과 const는 값이 할당되는 시점의 차이가 있다.

final은 컴파일 이후, 런타임 에서 값을 할당 할 수 있다.

그러나 한번 할당 된 값은 변수가 초기화 되기전에는 다시 다른 값으로 변경불가하다.

const는 컴파일 될 때, 값을 할당되는 것이다. 따라서, 런타임 시에는 더이상 값을 할당할수 가 없다.


---- English ----


Not only in Dart language, but in other development languages as well, it is a concept that you need to know.


Learn the concepts of mutable and immutable


mutable : mutable, immutable : immutable


for example,

class Car {
int? id;
String? model;

Car({this.id, this.model});
}

void main() {
Car car = Car(id:1, model:'m1');
Car car2 = car;

print('car, id=${car.id}, model=${car.model}');

car2.model = 'm2';

print('car2, id=${car.id}, model=${car.model}');
print('car, id=${car.id}, model=${car.model}');
}

result

car, id=1, model=m1
car2, id=1, model=m2
car, id=1, model=m2


I received car in car2 and changed the variable of car2, not only the model variable of car2,

The value of the model variable of car has also been changed.

In this case, the car's address value is copied to car2, so it has the same address value, so the car object variable is mutable.


If you want to create a Car object so that car2 has a different address value,

Car car2 = car;

Instead, Car car2 = Car(id:1, model:'m2'); If you create a new object with

will have


In another example,


final name1 = 'David';

const name2 = 'Paul';

Both are variables that are immutable.


This is because when you assign a value, it becomes final and const so that it becomes an immutable variable again.


The difference between final and const is when a value is assigned.


final can be assigned a value at runtime after compilation.


However, the value assigned once cannot be changed to another value until the variable is initialized.


const is a value assigned at compile time. Therefore, it is no longer possible to assign a value at runtime.





2022년 10월 25일 화요일

[Flutter] 함수 파라미터 설명



Dart언어에서 함수 파라미터 사용방법을 설명한다.


Positional parameters : 함수 인자 위치대로, 파라미터를 입력해줘야한다.

Named parameters : 함수 인자를 위치에 상관없이, 파라미터명 이름으로 지정하여 값을 입력해 줘야한다.

optional : 함수에서 받는 파라미터와 상관없이 입력할 값을 생략할 수 있는 사항인 경우이다.

required : 반드시 해당 파라미터는 값을 입력해 줘야한다.



아래 예제 코드에서,
Positional parameters 의 경우에서, 파라미터가 optional 인지, required 인지 예제이며,

또는

Named parameters 의 경우에서, 파라미터가 optional 인지, required 인지 예제를 설명한

사항이다.


class Car {
int? id;
String? model;

// Positional parameters
// int id, String model => required
Car(int id, String model) {
this.id = id;
this.model = model;
}
}

class Train {
int? id;
String? model;

// Named parameters
// int? id, String? model => optional
Train({int? id, String? model}) {
this.id = id;
this.model = model;
}
}

class Ship {
int? id;
String? model;

// Named parameters
// required int id, required String model => required
Ship({required int id, required String model}) {
this.id = id;
this.model = model;
}
}

class Bike {
int? id;
String? model;
int? price;

// Positional parameters
// int id => required, [String? model, int? price = 1000] => optional
Bike(int id, [String? model, int? price = 1000]) {
this.id = id;
this.model = model;
this.price = price;
}
}

class Airplan {
int? id;
String? model;
int? price;

// Named parameters
// int id => required, {String? model, int? price = 3000} => optional
Airplan(int id, {String? model, int? price = 3000}) {
this.id = id;
this.model = model;
this.price = price;
}
}

void main() {
Car car = Car(1, 'm1');
print('Car, id=${car.id}, model=${car.model}');

Train train = Train(model: 't1');
print('Train, id=${train.id}, model=${train.model}');

Ship ship = Ship(model: 's1', id: 3);
print('Ship, id=${ship.id}, model=${ship.model}');

Bike bike1 = Bike(4, 'b1');
print('Bike1, id=${bike1.id}, model=${bike1.model}, price=${bike1.price}');
Bike bike2 = Bike(4, 'b1', 5000);
print('Bike2, id=${bike2.id}, model=${bike2.model}, price=${bike2.price}');

Airplan airplan = Airplan(4, model: 'b1', price: 4000);
print('Airplan, id=${airplan.id}, model=${airplan.model}, price=${airplan.price}');
}


--- English ---

Describes how to use function parameters in Dart language.




Positional parameters: You must input parameters according to the position of the function argument.


Named parameters: Regardless of the location of the function argument, you must specify the parameter name and input the value.


optional : This is a case where the value to be input can be omitted regardless of the parameters received from the function.


required : The parameter must be entered with a value.



In the example code below,

In the case of Positional parameters, an example of whether the parameter is optional or required,


or


In the case of named parameters, this is an example of whether a parameter is optional or required.

2014년 1월 27일 월요일

Fragment 에서 서버에서 받은 이미지로 무한 반복 드래그 ViewPager 구현.


Fragment 에서 서버에서 받은 이미지로 무한 반복 드래그 ViewPager 구현.

ViewPager는 드래그할 경우, 앞뒤 이미지를 생성해 둔 상태에서 동작한다. 따라서 무한 드래그구현시, 마지막 끝에서도 맨첫번째 이미지가 드래그 되도록 하기위해서, 이미 첫번째 이미지가 끝에 이어서 생성되어있어야 한다. 따라서, 프로그램상으로는 실제  view(여기선 이미지)에 사용하는 개수는 실재view의 개수의 3배로 설정한다. 

@Override public int getCount() { return (mProductCnt * 3); }

그리고, 
@Override public void onPageSelected(int position) {

 를 통해서, 적절하게 viewpager를 관리해 주면, 실제 view가 반복해서 무한으로 반복되도록 보일수 있게 할 수 있다.


이번 포스트에서의 또다른 포인트는,
ViewPager 무한 반복 드래그 구현시, TextView, LinearLayout등의 컴포넌트 구현시에는 문제가 되지 않지만, ImageView의 경우, 다시 반복되는 View가 나타날때 Exception 발생으로 문제가 되었었던 내용이있다.
해결을 위해, ImageView사용대신, Linearlayout을 대신 사용하였고, 서버에서 ImageView로 이미지를 받은 이유로, 
Drawable drawable = mImageArray.get(position).getDrawable();
            linearlayout.setBackgroundDrawable(drawable);
와 같은 코드를 추가하였다.

그리고, 서버에서 받은 이미지가 view에 표시되기까지 시간이 걸리므로, 
handler를 사용하여 약간의 딜레이를 주도록 하였다.


소스코드는 아래와 같다.



1. res-layout-xml 파일

1
2
3
4
<android.support.v4.view.ViewPager
    android:id="@+id/product_viewpager"
       android:layout_width="260dp"
       android:layout_height="124dp"/>



2. src-java파일

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
private ViewPager mProductPager;
 
 
public void init(ProductList plist) {
        mProductList = plist;
        mProductCnt = mProductList.getProductList().size();
        if(mProductCnt > 1) {
            mProductLeftArrow.setVisibility(View.VISIBLE);
            mProductRightArrow.setVisibility(View.VISIBLE);
        }
        
        mImageArray = new ArrayList<ImageView>();
        for(int i=0; i<mProductCnt; i++) {
            ImageView iv = new ImageView(mainActivity);
            //mainActivity.mResourceResolver.loadImage(new ImageHTTPGet(mProductList.getProductList().get(i).getIMAGE_URL()), iv);
            mImageArray.add(iv);
        }
 
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                ImagePagerAdapter pagerAdapter = new ImagePagerAdapter(mainActivity.getApplicationContext());
                mProductPager.setAdapter(pagerAdapter);
                mProductPager.setCurrentItem(mProductCnt);
                mProductPager.setOnPageChangeListener(new OnPageChangeListener() {
                    @Override public void onPageSelected(int position) {
                        if(position < mProductCnt){
                            //Logger.getInstance().log(TAG, "1 position+mProductCnt = " + (position+mProductCnt));
                            mProductPager.setCurrentItem(position+mProductCnt, false);
                        }
                        else if(position >= (mProductCnt*2)){
                            //Logger.getInstance().log(TAG, "2 position-mProductCnt = " + (position-mProductCnt));
                            mProductPager.setCurrentItem(position - mProductCnt, false);
                        }
                        else {
                            position -= mProductCnt;
                            mPrevPosition = position;
                            //Logger.getInstance().log(TAG, "3 mPrevPosition === " + mPrevPosition);
                        }
                        
                        mProductPage.setText(((position%mProductCnt)+1) + "/" + mProductCnt);
                    }
                    @Override public void onPageScrolled(int position, float positionOffest, int positionOffsetPixels) {}
                    @Override public void onPageScrollStateChanged(int state) {}
                });
                
                mPrevPosition = 0;
                int currNo = mPrevPosition + 1;
                mProductPage.setText(currNo + "/" + mProductCnt);
            }
        }, 500);
}
 
private class ImagePagerAdapter extends PagerAdapter{
        private Context mContext;
        public ImagePagerAdapter( Context con) { super(); mContext = con; }
 
        @Override public int getCount() { return (mProductCnt * 3); }
 
        @Override public Object instantiateItem(View pager, int position) 
        {
            position %= mProductCnt;
            final int pagerAdapterPosition = position;
 
            LinearLayout linearlayout = new LinearLayout(mContext);
            Drawable drawable = mImageArray.get(position).getDrawable();
            linearlayout.setBackgroundDrawable(drawable);
            Logger.getInstance().log(TAG, "1 pagerAdapterPosition = " + pagerAdapterPosition);
            
            linearlayout.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
//                    String uri = "http://m.amgbiz.firstmall.kr/goods/view?no=" + ;
                    //Logger.getInstance().log(TAG, "2 pagerAdapterPosition = " + pagerAdapterPosition);
                    //Logger.getInstance().log(TAG, "2 mProductList.getProductList().get(pagerAdapterPosition).getGOODS_LINK() = " + mProductList.getProductList().get(pagerAdapterPosition).getGOODS_LINK());
                    mainActivity.clickShopTab(mProductList.getProductList().get(pagerAdapterPosition).getGOODS_LINK());//pagerAdapterPosition 값이 보이는 이미지의 position보다 1이 더큼.
                }
            });
            
            ((ViewPager)pager).addView(linearlayout);
            return linearlayout;
        }
 
        @Override public void destroyItem(View pager, int position, Object view) {
            ((ViewPager)pager).removeView((View)view);
        }
 
        @Override public boolean isViewFromObject(View view, Object obj) { return view == obj; }
 
        @Override public void finishUpdate(View arg0) {}
        @Override public void restoreState(Parcelable arg0, ClassLoader arg1) {}
        @Override public Parcelable saveState() { return null; }
        @Override public void startUpdate(View arg0) {}
        @Override public int getItemPosition(Object object) {
            return POSITION_NONE;
        }
    }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private ImageButton.OnClickListener onClick = new View.OnClickListener() {
        public void onClick(View v) {
            switch(v.getId()){
            case R.id.product_arrow_left:
                int pos = mProductPager.getCurrentItem();
                if(pos == 0 ) {
                    pos = mProductCnt - 1;
                } else {
                    pos --;
                }
                mProductPager.setCurrentItem(pos);
                break;
            case R.id.product_arrow_right:
                pos = mProductPager.getCurrentItem();
                if(pos == (mProductCnt - 1) ) {
                    pos = 0;
                } else {
                    pos ++;
                }
                mProductPager.setCurrentItem(pos);
                break;
                        }
        }
    };