سایر مقالات این دسته
تاریخچه و خصوصیات اندرویداجزای تشکیل دهنده سیستم عامل اندرویدآشنایی با API های اندرویدایجاد،ساخت و اجرای اولین برنامه اندرویدیکار با دکمه ها در اندرویدکار با تکست باکس ها در اندرویدکار با تکست ویو در اندرویدکار با گرید ویو در اندرویدکار با وب ویو در اندرویدکار با اسکرول ویو در اندرویدکار با اسکرول ویو افقیکار با الرت دیالوگ (AlertDialog)در اندرویدکار با ایمیج باتن(Image Button) در اندرویدکار با توگل باتنکار با چک باکس (Checkbox) در اندرویدکار با الرت دیالوگ (AlertDialog)در اندروید قسمت دوکار با ریتینگ بار(Rating bar) در اندرویدرفتن از یک اکتویتی به اکتویتی دیگرکار با نوتیفیکیشن ها (Notifications )در اندرویدکار با صوت در برنامه نویسی اندرویدکار با ویبره(Vibrator) در اندرویدکار با دوربین در اندرویدکار با دوربین در اندرویدکار با ویدیو ویو (VideoView)در اندرویدکار با شبکه وای فای (Wifi)در اندرویدکار با لیست ویو (ListView) در اندرویدکار با سیک بار (SeekBar) در اندرویدکار با دکمه بازگشت در اندرویدکار با AutoCompleteTextView در اندرویدتغییر فونت در اندرویدکار با لایه TableLayout در اندرویدکار با لیست کشویی (Spinner) در اندرویدکار با CalendarView در اندرویدساخت شمارنده در اندرویدکار با title bar در اندرویدکار با منو (Menu)در اندرویدکار با لیست ویو (Listview) قسمت دومطراحی رابط کاربری در اندروید قسمت اولطراحی رابط کاربری در اندروید قسمت دوم(طراحی گرد)کار با استایل در اندرویدکار با لایه AbsoluteLayout در اندرویدطراحی رابط کاربری در اندروید کار با gradientکار با کلیپ بورد(ClipBoard)در اندروید کار با مولتی تاچ(Multitouch ) در اندروید+سورس کدکار با OnLongClick در اندرویدکار با منوی زمینه (ContextMenu ) در اندرویدکار با حرکات (Gesture) در اندرویدکار با (AudioCapture) در اندروید+سورس کدکار با موتور Speech در اندروید + سورسکار با PhoneCall در اندرویدساخت لیست ویو سفارشی در اندروید+سورسساخت Toastسفارشی در اندرویدانتقال برنامه به حافظه sdکار با TextWatcher در اندروید+سورستغییر رنگ محیط Eclipse طراحی رابط کاربری در اندروید کار با Canvasساخت اکشن بار سفارشی در اندروید+سورسساخت الرت دیالوگ سفارشی در اندرویدساخت برنامه نمایش مقدار شارژ باتری در اندرویدایجاد افکت رنگی بروی تصاویر در اندروید+سورسساخت آپشن منوی سفارشی در اندروید+سورسساخت دکمه سه بعدی با Selectorسخنان بزرگان برنامه نويسيوارد كردن پروژه در محيط ايكليپساضافه کردن switch,case به لیست ویوبارش برف بروی تصویر + سورسکار با فیلتر hue رنگی کردن تصویر انتخاب و پخش فایل صوتی از حافظه گوشی+سورساضافه کردن چک باکس به لیست ویوکار با ShelfView یا نمایش کتابخانه ای + سورسکار با TabHost،اضافه کردن تب به برنامه های اندرویدآموزش کامل ساخت اکشن بار سفارشی+سورسساخت برنامه های واکنش گرا(ریسپانسیو) در اندرویدقسمت دوم صفحات 7 اینچ به بالااضافه کردن انیمیشن به دکمه+سورسکار با View Switcher در اندروید + سورسکار با فیلتر Blur Mask + سورسدانلود پک کامل آیکون های طراحی اندرویدکار با sharedPreferences در اندروید+سورسآموزش کار با proguard،محافظت از برنامه اندرویدپخش فایل صوتی (MP3) از ادرس اینترنتی+سورسپخش ویدیو از آدرس اینترنتی(URL) در اندروید+سورسگوشی های و تبلت های مطرح تا چینی به ساده ترین روشپاسخ به رویداد های WebVeiw دسترسی به وب ویو با استفاده از جاوااسکریپتساخت ExpandableListView به ساده ترین شکل+سورسکار با WIFI اکسس+سورسساخت تقویم هجری برای اندروید+سورسapp rateدانلود و نمایش تصویر در ListView+سورسدانلود و نمایش فایل متنی+سورسکار با کلاس های پایه اکتیویتیآینه کردن تصویر+سورسافزودن آیتم منو سفارشی بهActionBar+سورسارسال اطلاعات از دیتابیس به GridView + سورسدسترسی به Api هایREST قسمت اولتغییر فونت لیست ویوفعال سازی و معرفی بخش های Android developer options بخش اول کار با JSON در اندرویدآموزش ساده نصب شبیه ساز اندروید Genymotion

آموزش ساده نصب شبیه ساز اندروید Genymotion
1395/10/22

آموزش زامارین،کار با سوئیچ
1395/09/06

استفاده آسان از Google reCaptcha در کد phpجهت جلوگیری از اسپم
1395/08/08

کار با JSON در اندروید
1395/08/02

وارد کردن اطلاعات از Excel به مای اس کیو ال با PHP
1395/07/24

دانلود و نمایش تصویر در ListView+سورس


رضا نقی لو 1395/01/28

به نام خدا، بابت چند روز دیرکرد در آپدیت آموزش های مربوط به برنامه نویسی شبکه در اندروید عذرخواهی میکنم.دلیل این تاخیر آماده کردن یک آموزش کامل و جامع در این زمینه بود.توی این جلسه میخواهیم با دانلود چند فایل تصویری و نمایش اون ها در لیست ویو ListView آشنا بشیم. در جلسات گذشته با نحوه دانلود و نمایش تصویر،فایل ویدئویی و  فایل صوتی از آدرس های اینترنتی آشنا شده ایم.در این آموزش ما با AsyncTask و دریافت اطلاعات از فایل String.xml به صورت کامل آشنا خواهیم شد.

برای شروع کار یک پروژه جدید ایجاد میکنیم.برنامه ما نیاز به دوتا لایه داره یکی از لایه ها activity_main.xml که لایه اصلی برنامه به حساب میاد هست و دیگری یک لایه Custom یا سفارشی هست.در جلسات گذشته با نحوه ساخت لیست ویو سفارشی آشنا شدیم و میدانیم که برای نمایش یک تصویر و محتوای مربوط به آن نیاز داریم تا یک لایه سفارشی برای Lsitview ایجاد کنیم(برای آشنای با ساخت لایه جدید به این آموزش مراجعه کنید).کدهای کامل لایه activity_main.xml را در زیر میتوانید ببیند که تنها از یک Listview تشکیل شده است.

 <?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/custom_list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:dividerHeight="1dp">
</ListView>

بعد از اینکه لایه برنامه رو تکمیل کردیم میریم سراغ لایه سفارشی برنامه و عناصر گرافیکی اون.در داخل این لایه از یک ImageView برای نمایش تصاویر و از سه عدد TextView برای نمایش عنوان،ارائه دهنده تصویر و زمان مربوط به آن.دقت داشته باشید که ما در Imageview از یک تصویر پیشفرض استفاده کرده ایم تا زمان دانلود تصاویر مدنظر ما آن عکس نمایش داده شود.(کدهای مربوط به لایه سفارشیlist_row_layout.xml).

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="50dp"
android:padding="8dp">

<ImageView
android:id="@+id/thumbImage"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
android:background="@drawable/placeholder" />

<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/thumbImage"
android:minLines="2"
android:paddingTop="5dp"
android:textStyle="bold" />

<TextView
android:id="@+id/reporter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/title"
android:layout_marginTop="5dp"
android:layout_toRightOf="@id/thumbImage" />

<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/reporter"
android:layout_alignParentRight="true" />

</RelativeLayout>

بعد از اینکه لایه های برنامه رو تکمیل کردیم،نوبت اون میرسه که کلاس های برنامه رو ایجاد کنیم (برای آموزش ساخت کلاس به این آموزش مراجعه کنید)و کدهای جاوای برنامه رو بنویسیم.برنامه ما از چهار تا کلاس تشکیل شده کلاس اصلی ما MainActivity هست.در داخل این کلاس ابتدا listView با یک مقدار final معرفی می کنیم تا مقدارش همیشه ثابت باشه.سپس برای لیست ویو یک OnItemClickListener معرفی می کنیم تا هر زمانی کاربر بر روی هر کدام از آیتم های آن کیلیک کرد یک پیام Toast رو نمایش بده.سپس یک کلاس خصوصی با نام ArrayList ایجاد میکنم تا اطلاعات مربوط به آدرس اینترنتی تصاویر و متن های آن ها میباشید رو به لیست ویو انتقال دهد.(کدهای کامل کلاس MainActivity).

 /*
* appinapps.com
* آموزش برنامه نویسی به زبان ساده
*/
import java.util.ArrayList;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.Toast;
import com.appinapps.imageloader.R;

public class MainActivity extends Activity {

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

ArrayList<ListItem> listData = getListData();

final ListView listView = (ListView) findViewById(R.id.custom_list);
listView.setAdapter(new CustomListAdapter(this, listData));
//ایجاد یک لیسنر برای لیست ویو جهت اعمال قابلیت کیلیک به هر ایتم آن
listView.setOnItemClickListener(new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
ListItem newsData = (ListItem) listView.getItemAtPosition(position);
//اضافه کردن یک توست به کیلیک لیست ویو جهت نمایش کلیک هر آیتم
Toast.makeText(MainActivity.this, "Selected :" + " " + newsData,  Toast.LENGTH_LONG).show();
}
});
}

//دریافت اطلاعات مربوط به تصاویر و متن هر تصویر و نمایش آن در لیست ویو
private ArrayList<ListItem> getListData() {
ArrayList<ListItem> listMockData = new ArrayList<ListItem>();
String[] images = getResources().getStringArray(R.array.images_array);
String[] headlines = getResources().getStringArray(R.array.headline_array);

for (int i = 0; i < images.length; i++) {
ListItem newsData = new ListItem();
newsData.setUrl(images[i]);
newsData.setHeadline(headlines[i]);
//نمایش نام ارائه دهنده
newsData.setReporterName("Appinapps");
//نمایش تاریخ ارائه مطلب
newsData.setDate("february 8, 2016, 18:35");
listMockData.add(newsData);
}
return listMockData;
}
}

در ادامه یک کلاس جدید با نام ImageDownloaderTask ایجاد میکنم.در داخل این کلاس با استفاده از AsyncTask تصویر رو از URL های که دادیم دانلود می کنم و در لیست ویو به نمایش درمیاوریم.در ابتدا بهتر است با AsyncTask و قابلیت های اون به صورت کامل آشنا بشیم.AsyncTask چیست؟ AsyncTask یک کلاس انتزاعی اندروید است که به اپلیکیشن‌های اندروید کمک می‌کند تا ترد اصلی UI را به صورت مؤثر مدیریت کنند. کلاس AsyncTask به ما امکان می‌دهد تا تسک‌های زمان‌بر را اجرا کرده و حاصل را روی ترد اصلی بدون تأثیر گذاشتن روی آن نمایش دهیم. چه‌موقع از AsyncTask استفاده کنیم؟ فرض کنیم شما یک اپلیکیشن ساده ساخته‌اید که یک فایل png را هنگام اجرای برنامه از اینترنت دانلود می‌کند. نمودار وضعیت زیر مجموعه عملیاتی را نشان می‌دهد که وقتی اپلیکیشنتان را اجرا می‌کنید اتفاق می‌افتند.

همچنان‌که دانلود فایل از سرور در حال انجام است، اپلیکیشن غیر قابل استفاده می‌شود تا زمانی که ترد اصلی منتظر اتمام عملیات دانلود است. برای مواجه با این‌گونه مشکلات می‌توانیم یک ترد جدید بسازیم و متد run آن را بگونه تغییر دهیم که این فراخوانی شبکه را اجرا کند دقیقاً شبیه کاری که معمولاً در برنامه‌های عادی جاوا انجام می‌دهیم. درنتیجه UI پاسخگو باقی می‌ماند. به‌ این علت که toolkit رابط کاربری اندروید thread safe نیست، پیاده‌سازی این مسأله با چند ترد ممکن است خود مشکلات اضافی جدیدی را وقتی سعی کنیم UI را طبق نتایجی که از اجرای عملیات دانلود بدست می‌آید آپدیت کنیم، ایجاد کند. اندروید تمام این مشکلات را درنظر داشته و کلاس اختصاصی‌ای را به نام «‌AsyncTask» ساخته تا تسک‌ها و عملیاتی را که نیاز است در پس‌زمینه به صورت ناهمگام اجرا شوند، مدیریت کند. نکته : AsyncTask فقط باید برای تسک‌های استفاده شود که تنها چند ثانیه طول می‌کشند، بعضی تسک‌ها ممکن است ترد را برای مدت زیادی در حال اجرا نگه‌دارند در این صورت این تسک‌ها باید به‌وسیله پکیج «java.util.concurrent» مدیریت شوند. چهار مرحله AsyncTask وقتی یک تسک ناهمگام از ترد اصلی UI اجرا می‌شود از چهار مرحله می‌گذرد:

onPreExecute : قبل از اجرای تسک فراخوانی می‌شود، در تئوری قبل از اینکه متد «doInBackground» روی تردUI فراخوانی شود. این متد اغلب برای آماده‌سازی اجرای تسک استفاده می‌شود (مثل نمایش نوار پیشرفت در رابط کاربری)

doInBackground: کدهایی که اجرای آن‌ها زمان‌بر است باید در این متد نوشته شوند. وقتی متد execute در ترد اصلی UI فراخوانی شد این متد با پارامترهایی که به آن ارسال شده اجرا می‌شود.

onProgressUpdate: متدdoInBackground در هرلحظه با فرخوانی «publishProgress» این متد را اجرا می‌کند. این متد می‌تواند برای نمایش پیشرفت کار به هر صورت، در رابط کاربر استفاده شود.

onPostExecute: وقتی پردازش محاسبات پس‌زمینه در متد «doInBackground» پایان یافت فراخوانی می‌شود. نتایج «doInBackground» به این متد فرستاده می‌شوند.

کنسل کردن تسک تسک می‌تواند با فراخوانی متد cancel(boolean) کنسل شود. اجرای این متد باعث فراخوانی‌های بعدی isCancelled() خواهد شد تا پاسخش true شود. بعد از اجرای این متد به جای متد onPostExecute() متد onCancelled(Object) فراخوانی می‌گردد.

 

بعد از اینکه AsyncTask رو پیاده سازی کردیم،نوبت به این میرسه که از یک متد HttpURLConnection استفاده کنیم.این متد به ما کمک میکنه اطلاعات دریافتی از Network رو بررسی کنیم و سپس بر اساس ان اطلاعات کاراهای را انجام دهیم،به عنوان مثال در این اموزش ما از HttpURLConnection رو خواستیم تا شبکه رو بررسی کنه و در صورت OK بودن تصاویر رو دانلود و نمایش بده از طریق InputStream.در غیر این صورت عمل عکس را انجام دهد.(کدهای کاملImageDownloaderTask).

 /*
* appinapps.com
* آموزش برنامه نویسی به زبان ساده
*/
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.URL;
import org.apache.http.HttpStatus;
import com.appinapps.imageloader.R;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ImageView;
class ImageDownloaderTask extends AsyncTask<String, Void, Bitmap> {

private final WeakReference<ImageView> imageViewReference;

public ImageDownloaderTask(ImageView imageView) {
imageViewReference = new WeakReference<ImageView>(imageView);
}

@Override
protected Bitmap doInBackground(String... params) {
return downloadBitmap(params[0]);
}

@Override
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}

if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
if (imageView != null) {
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
} else {
//ایجاد یک تصویر جهت نمایش درصورت عدم دانلود شدن تصویر یا حالت wait
Drawable placeholder =  imageView.getContext().getResources().getDrawable(R.drawable.placeholder);
imageView.setImageDrawable(placeholder);
}
}

}
}

//ایجاد یک کانکشن برای بررسی اتصال به کانکشن 
private Bitmap downloadBitmap(String url) {
HttpURLConnection urlConnection = null;
try {
URL uri = new URL(url);
urlConnection = (HttpURLConnection) uri.openConnection();

int statusCode = urlConnection.getResponseCode();
if (statusCode != HttpStatus.SC_OK) {
return null;
}

InputStream inputStream = urlConnection.getInputStream();
if (inputStream != null) {
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
return bitmap;
}
} catch (Exception e) {
urlConnection.disconnect();
Log.w("ImageDownloader", "Error downloading image from " + url);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return null;
}
}

کلاس سومی که میخواهیم ایجاد کنیم یک کلاس برای سفارشی سازی لیست ویو است،نام این کلاس را  CustomListAdapter  قرار میدهیم در داخل این فایل یک کلاس CustomListAdapter ازنوع public ایجاد میکنم و آرایه های رو که ایجاد کردیم بهش متصل میکنم.این کلاس چند تا ویژگی داره که اصلی ترین اون getView هست.در داخل متد getView یک holder میسازیم تا اطلاعات مربوط به من.تاریخ و تصویر رو به صورت یکجا و در یک ایتم نمایش دهد.(کدهای کامل کلاس CustomListAdapter).

 /*
* appinapps.com
* آموزش برنامه نویسی به زبان ساده
*/


import java.util.ArrayList;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.appinapps.imageloader.R;

public class CustomListAdapter extends BaseAdapter {
private ArrayList<ListItem> listData;
private LayoutInflater layoutInflater;

//اتصال ارایه به آداپتر
public CustomListAdapter(Context context, ArrayList<ListItem> listData) {
this.listData = listData;
layoutInflater = LayoutInflater.from(context);
}

@Override
public int getCount() {
return listData.size();
}

@Override
public Object getItem(int position) {
return listData.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.list_row_layout, null);
holder = new ViewHolder();
holder.headlineView = (TextView) convertView.findViewById(R.id.title);
holder.reporterNameView = (TextView) convertView.findViewById(R.id.reporter);
holder.reportedDateView = (TextView) convertView.findViewById(R.id.date);
holder.imageView = (ImageView) convertView.findViewById(R.id.thumbImage);
convertView.setTag(holder);

} else {
holder = (ViewHolder) convertView.getTag();
}

ListItem newsItem = listData.get(position);
holder.headlineView.setText(newsItem.getHeadline());
holder.reporterNameView.setText("by, " + newsItem.getReporterName());
holder.reportedDateView.setText(newsItem.getDate());

if (holder.imageView != null) {
new ImageDownloaderTask(holder.imageView).execute(newsItem.getUrl());
}

return convertView;
}

static class ViewHolder {
TextView headlineView;
TextView reporterNameView;
TextView reportedDateView;
ImageView imageView;
}
}

در ادامه میخواهیم فایل String.xml رو بررسی کنیم.در داخل این فایل یک تگ array با نام images_array میسازیم و سپس در داخل ایتم های این ارایه ادرس های اینترنتی تصاویر را وارد میکنم.در ادامه نیز یک تگ آرایه array جدید با نام headline_array ایجاد می کنیم که وظیفه در برگیری متن های مربوط به تصاویر را برعهده دارند.(کدهای String.xml).

 <?xml version="1.0" encoding="utf-8"?>
<!-- اپ این اپس 
Appinapps.com
آموزش برنامه نویسی
-->

<resources>
<string name="app_name">Async ListView</string>

<!-- ادرس های اینترنتی تصاویر -->
<array name="images_array">
<item>http://appinapps.com/upload/articlesappinapps_wifi_ac.png</item>
<item>http://appinapps.com/upload/articlesxamarin_icon_five_appinapps.png</item>
<item>http://appinapps.com/upload/articlesVertical-expandable-menu-PSD.png</item>
<item>http://appinapps.com/Articles_View.aspx?aid=235</item>
<item>http://appinapps.com/Articles_View.aspx?aid=234</item>
<item>http://appinapps.com/Learning.aspx?gid=7</item>
<item>http://appinapps.com/Learning.aspx?gid=13</item>
</array>

<!-- اطلاعات مربوط به هر تصویر -->
<array name="headline_array">
<item>کار با WIFI اکسس+سورس</item>
<item>آموزش زامارین،قسمت پنجم</item>
<item>ساخت ExpandableListView به ساده ترین شکل </item>
<item>ساخت تقویم هجری برای اندروید+سورس</item>
<item>فراخوانی فایل php از طریق jquery و ajax</item>
<item>رابط کاربری اندروید</item>
<item>آموزشphpاز مقدماتی تا پیشرفته</item>
</array>
</resources>

این را هم میدانیم که باید برای برنامه های که نیاز به اینترنت دارند باید  دسترسی مربوط به اینترنت (uses-permission android:name="android.permission.INTERNET) را در فایل Manifest.xml اضافه کنیم.

عناوین دوره های رایگان آموزشی کار با شبکه و ارتباطات در برنامه نویسی اندروید:

1.پاسخ به رویداد های WebVeiw

2.دسترسی به وب ویو با استفاده از جاوااسکریپت

3.دانلود و نمایش یک عکس از اینترنت

4.دانلود و نمایش بیش از یک عکس از اینترنت

5.دانلود و نمایش یک فایل متنی

6.سترسی به API های REST

7.ترجمه عبارت های JSON

8.ترجمه XML

9.انتقال داده از طریق NFC

10.برنامه نویسی سوکت

11.ساخت برنامه هواشناسی

در آخر این اموزش هم توصیه میکنم که سورس این اموزش را از این لینک دانلود کنید.موفق باشید

 

 

فایلهای ضمیمه
توجه! هیچ فایل ضمیمه ای برای این مطلب یافت نشد
درباره نویسنده
admin2
رضا نقی لو
androiddev160@gmail.com
نظرات شما
نظر جدید
    User name
    ناشناس

    سلام ممنون از مطالب خوبتون اگه امکانش باشه لطف کنین گرفتن عکس از دیتابیس رو آموزششو بزارین اگه طبق این آموزش بخواییم تعداد بالایی عکس از اینترنت بگیریم خوب به مشکل برمیخوریم.

    1395/06/07 10:54 AM

    User name
    ناشناس

    سلام ممنون از مطالب خوبتون اگه امکانش باشه لطف کنین گرفتن عکس از دیتابیس رو آموزششو بزارین اگه طبق این آموزش بخواییم تعداد بالایی عکس از اینترنت بگیریم خوب به مشکل برمیخوریم.

    1395/06/07 10:55 AM