PDA

View Full Version : راهنمایی برای نوشتن یک برنامه با چند کلاس



sina4everafter
چهارشنبه 25 تیر 1393, 16:07 عصر
سلام. ممنون میشم اگر راهنماییم کنید.

من می خوام یه برنامه ای بنویسم که باید چند تا کلاس داشته باشه. یه کلاس باید درست کنم به نام Category که یه سری اسم و از فایل xml پارس کنه. و یه کلاس دیگه به یه نام دیگه ای که باید یه سری اطلاعات از اون کلاس Category در این کلاس تعریف بشه. و حالا باید توی کلاس اصلی برنامم هر موقع که لازم شد از اون کلاسا استفاده کنم. و باید اون کلاساها هم خیلی کلی باشن. یعنی ممکنه مثلا من اول برنامه بخوام Category و دکمه در نظر بگیرم و یه موقعه ای بخوام یه لیست ویو در نظر بگیرم. منظورم اینه که اصلا نباید کلاسام انحصاری تعریف بشه.
راستیتش من اصلا موندم که چطوری این برنامه رو بنویسم.
اگر راهنماییم کنید ممنون میشم.

parvizwpf
چهارشنبه 25 تیر 1393, 16:46 عصر
1- این category در اصل چی هست؟
2- اطلاعات مریوط به category چی هست؟
3-اینکه میگید دکمه باشه یا لیست ویو میشه مفصل تر بگید یعنی چی؟

sina4everafter
چهارشنبه 25 تیر 1393, 18:36 عصر
ببینید من قراره یه برنامه مبدل واحد بنویسم.
این برنامه یه سری دکمه داره مثه: طول، حجم، زاویه و ... . یه بار این برنامه فقط با یک کلاس نوشتم.خیلی کد ها زیاد شده بود. حدودا 3000 خط شده بود.مثلا وقتی که روی دکمه "طول" کلیک می کردی، layout مربوط یه طول inflate میشد و واحد های طول و نشون می داد.و هم چنین یه اسپینر هم داشت که اینجا زیاد مهم نیست.
من بار اول این برنامه رو فقط با یه کلاس نوشتم.
اما الان باید طوری برنامه رو بنویسم که خیلی به قول معروف مهندسی باشه.
الان منظوره من از category همون لیست دکمه هاست که اسم های دکمه ها از یه فایل xml که داخل فولدر assets تعریف می کنم ساخته میشه. با استفاده از کلاس XmlPullParser. که داخل یه لوپ while دکمه ها رو می سازه.
مشکل من اینه که اصلا نمی دونم چطوری برای هر کدوم یه کلاس جدا درست کنم
من کارآموز اندرویدم. امروز توی شرکت بم گفتن که باید برنامه رو طوری بنویسی که یه الگوی کلی باشه. گفت مثلا طوری نباشه که فقط بتونیم از اون لیست نام ها فقط برای دکمه یا فقط برای لیست ویو استفاده کنیم.
من خودم کلاس درست می کنم و اون کلاس و از کلاس اصلیم ارث بری می کنم. ولی اصلا کارم از ریشه غلطه. برنامه اجرا هم نمیشه. نمی دونم درست توضیح دادم یا نه.
اما اگه هر چقدر هم کمکم کنید ممنون میشم.

sina4everafter
پنج شنبه 26 تیر 1393, 09:59 صبح
ممنون میشم اگر راهنماییم کنید.

mohammadi1366
پنج شنبه 26 تیر 1393, 12:35 عصر
سلام
شما باید یک کلاس بسازید بعد از اون یه ابجکت توی کلاس اصلیت بگیری و بعد متود هاش رو اجرا کنی
یا اینکه اینجوری کار کنی :
package com.abc.example;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;

public class FindUs extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.findUs);

Button first = (Button) findViewById(R.id.first);
Button second = (Button) findViewById(R.id.second);
Button third = (Button) findViewById(R.id.third);
Button fourth = (Button) findViewById(R.id.fourth);

first.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
startActivity(new Intent("com.abc.example.FIRST"));
}
});

second.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
startActivity(new Intent("ccom.abc.example.SECOND"));
}
});

third.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
startActivity(new Intent("com.abc.example.THIRD"));
}
});

fourth.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
startActivity(new Intent("com.abc.example.FOURTH"));
}
});
}
و کلاس دومی اینه :
package com.abc.example;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;

public class First extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.first);

Button callFirst= (Button) findViewById(R.id.callfirst);
Button mapFirst= (Button) findViewById(R.id.mapfirst);

callFirst.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
String phoneNumber = "tel:+18000000000";
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse(phoneNumber));
startActivity(callIntent);

}
});

mapFirst.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
String url = "grab google directions for this place";
Intent mapIntent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(url));
startActivity(mapIntent);
}
});
}

sina4everafter
پنج شنبه 26 تیر 1393, 13:19 عصر
ممنون. ولی من این کار و انجام میدم ولی اینطوری نمی خوام باشه. شما الان دو تا لیوت دارین. و اینکه دکمه ها باید با یه حلقه فور ایجاد بشه.
برنامه باید اینطوری باشه که یه کلاسی تعریف بشه و یک فایل xml و پارس کنه. حالا توی کلاس اصلی ممکنه بخوایم از اون فایل xml ای که پارس شده برای نام های یه دکمه استفاده کنیم یا اینکه برای لیست های یه لیست ویو. نمی دونم درست توضیح میدم یا نه.
مشکل من الان اینه که نمی دونم چه طور باید موقعی که لازم هست از کلاس دوم داخل کلاس اصلی برنامم استفاده کنم. یعنی همون کلاسی که فایل xml و پارس می کنه.
از روی کلاس دوم هم یه آبجکت درست می کنم ولی برنامه کرش می کنه.

sina4everafter
جمعه 27 تیر 1393, 23:25 عصر
ممنون میشم اگر راهنماییم کنید. خیلی این مسئله برام مهمه.

poorman
شنبه 28 تیر 1393, 22:25 عصر
سلام

من نمیتونم نمونه کدی بدم یا خیلی دقیق راهنمایی کنم چون زیاد ساختار برنامتون برام مفهوم نبود

روش کار رو تقریبا خودتون میدونید، من یکم بیشتر توضیح میدم راجع بهش

شما یک کلاس به اسم Category میسازید

یک متغیر از جنس آرایه یا لیست به اسم cats نیاز دارید که رشته های خونده شده از xml رو توش بریزید

توی متد اصلی کلاس public Category(){} باید عملیات خواندن از xml رو انجام بدید و مقادیر رو داخل آرایه یا لیست cats بریزید

حالا بسته به نیازتون توی این کلاس چند تا تابع دیگه مینویسید که توی اکتیویتی ازشون استفاده کنید

مثلا یک تابع مینویسید به اسم getAllCats که آرایه یا لیست cats رو return میکنه

یا یک کلاس به اسم getCat_atPosition که یک عدد n میگیره و خونه n ام آرایه یا لیست رو برمیگردونه

حالا توی اکتیویتی برفرض میخواین این دسته بندی هارو بریزید داخل آداپتر یک لیست ویو

کافیه یک نمونه از این کلاس رو بسازید و تابع getAllCats رو صدا بزنید تا آرایه دسته بندی ها رو برگردونه

مثلا به صورت زیر:

String[] cats = new Category(context).getAllCats();

یا اگه میخواین برای مقدار دادن یک دکمه استفاده کنید از تابع getCat_atPosition

امیدوارم مفید واقع بشه

sina4everafter
یک شنبه 29 تیر 1393, 12:30 عصر
سلام. ممنون از راهنماییتون. خیلی کمک کرد. من تا اینجای کد و نوشتم. فقط نمی دونم چرا موقعی که می خوام Button ایجاد کنم برنامه کرش می کنه.

کلاس Category

import java.io.InputStream;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;

import android.content.Context;


public class Category {

//---XmlPullParserFactory---
XmlPullParserFactory xmlPullParserFactoryObject;

//---Context---
Context context;

//---Array---
String[] arrayCategory;

//---Category Method---
public Category(){

//---try...catch---
try {

//---XmlPullParser---
xmlPullParserFactoryObject = XmlPullParserFactory.newInstance();
XmlPullParser xmlPullParserObject = xmlPullParserFactoryObject.newPullParser();

//---Xml file from assets folder---
InputStream input_Stream = context.getApplicationContext().getAssets().open("sample.xml");
xmlPullParserObject.setInput(input_Stream, null);

//---parse to integer---
int arrayLength = Integer.parseInt(xmlPullParserObject.toString());

//---Create Array---
arrayCategory = new String[arrayLength];

//---while---
while (xmlPullParserObject.getEventType() != XmlPullParser.END_DOCUMENT) {

if (xmlPullParserObject.getEventType() == XmlPullParser.START_TAG &&
xmlPullParserObject.getName().equals("button")) {
int counter = 0;
arrayCategory[counter] = xmlPullParserObject.getAttributeValue(1);
counter++;
}
xmlPullParserObject.next();
}

} catch (Exception e) {
e.printStackTrace();
}
}

public String[] getAllCats(){

return arrayCategory;
}
}


و این هم کلاس اکتیویتی.


import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.widget.Button;
import android.widget.LinearLayout;

public class MainActivity extends Activity {

Context context;

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

//---Create instance from Category---

String[] returnCatsArrayString = new Category().getAllCats();
LinearLayout li = (LinearLayout) findViewById(R.id.li);

for (int i = 0; i < 2; i++) {


Button btn = new Button(this);
li.addView(btn);
// btn.setText(returnCatsArrayString[i]);
}
}
}


مشکل از داخل حلقه for هست.

poorman
یک شنبه 29 تیر 1393, 13:28 عصر
متن خطا رو بذارید ببینم مشکل از کجاست

الان شما دکمه ها رو که دارید ایجاد میکنید وقتی میخواید متن رو ست کنید چرا StringValue رو ست میکنید ؟؟؟

شما یک آرایه رشته از کلاستون گرفتید دیگه، حالا توی حلقه وقتی میخواین متن رو ست کنید از returnCastArray[i] استفاده کنید

احتمال داره مشکل از همینجا باشه

sina4everafter
یک شنبه 29 تیر 1393, 13:48 عصر
بله. اگه الان دوباره کد و نگاه کنید ویرایش کردم، همین کار و انجام دادم.خط آخر که کامنت هست اجرا نمیشه.

sina4everafter
یک شنبه 29 تیر 1393, 13:58 عصر
این هم کل لاگ.

07-21 01:01:07.951: E/AndroidRuntime(12810): FATAL EXCEPTION: main
07-21 01:01:07.951: E/AndroidRuntime(12810): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.asr24.cando.unitconversion/com.asr24.cando.unitconversion.MainActivity}: java.lang.NullPointerException
07-21 01:01:07.951: E/AndroidRuntime(12810): at android.app.ActivityThread.performLaunchActivity(A ctivityThread.java:2211)
07-21 01:01:07.951: E/AndroidRuntime(12810): at android.app.ActivityThread.handleLaunchActivity(Ac tivityThread.java:2261)
07-21 01:01:07.951: E/AndroidRuntime(12810): at android.app.ActivityThread.access$600(ActivityThre ad.java:141)
07-21 01:01:07.951: E/AndroidRuntime(12810): at android.app.ActivityThread$H.handleMessage(Activit yThread.java:1256)
07-21 01:01:07.951: E/AndroidRuntime(12810): at android.os.Handler.dispatchMessage(Handler.java:99 )
07-21 01:01:07.951: E/AndroidRuntime(12810): at android.os.Looper.loop(Looper.java:137)
07-21 01:01:07.951: E/AndroidRuntime(12810): at android.app.ActivityThread.main(ActivityThread.jav a:5103)
07-21 01:01:07.951: E/AndroidRuntime(12810): at java.lang.reflect.Method.invokeNative(Native Method)
07-21 01:01:07.951: E/AndroidRuntime(12810): at java.lang.reflect.Method.invoke(Method.java:525)
07-21 01:01:07.951: E/AndroidRuntime(12810): at com.android.internal.os.ZygoteInit$MethodAndArgsCa ller.run(ZygoteInit.java:737)
07-21 01:01:07.951: E/AndroidRuntime(12810): at com.android.internal.os.ZygoteInit.main(ZygoteInit .java:553)
07-21 01:01:07.951: E/AndroidRuntime(12810): at dalvik.system.NativeStart.main(Native Method)
07-21 01:01:07.951: E/AndroidRuntime(12810): Caused by: java.lang.NullPointerException
07-21 01:01:07.951: E/AndroidRuntime(12810): at com.asr24.cando.unitconversion.MainActivity.onCrea te(MainActivity.java:29)
07-21 01:01:07.951: E/AndroidRuntime(12810): at android.app.Activity.performCreate(Activity.java:5 133)
07-21 01:01:07.951: E/AndroidRuntime(12810): at android.app.Instrumentation.callActivityOnCreate(I nstrumentation.java:1087)
07-21 01:01:07.951: E/AndroidRuntime(12810): at android.app.ActivityThread.performLaunchActivity(A ctivityThread.java:2175)
07-21 01:01:07.951: E/AndroidRuntime(12810): ... 11 more

poorman
یک شنبه 29 تیر 1393, 14:15 عصر
مشکل از اینه که آرایه شما فقط خونه اولش مقدار داده شده

توی تابع getAllCats شما int counter = 0 رو داخل حلقه قرار دادید، که باعث میشه آرایه به خونه بعدی نره و هربار خونه صفر آرایه مقدار داده بشه، بنابراین سایر خونه ها خالی میمونه

sina4everafter
دوشنبه 30 تیر 1393, 22:07 عصر
سلام.
من این برنامه رو نوشتم. الان اجرا میشه. قبل از این اصلا اجرا نمیشد و برنامه کرش می کرد. اما الا اجرا میشه ولی به حلقه for نمیرسه.

این کد کلاس دومم هست:


import java.io.InputStream;


import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;


import android.content.Context;




public class Category {

//---XmlPullParserFactory---
XmlPullParserFactory xmlPullParserFactoryObject;

//---Context---
Context context;

int counter = 0;

//---Array---
String[] arrayCategory;

//---Category Method---
public Category(Context context){
this.context = context;

//---try...catch---
try {

//---XmlPullParser---
xmlPullParserFactoryObject = XmlPullParserFactory.newInstance();
XmlPullParser xmlPullParserObject = xmlPullParserFactoryObject.newPullParser();

//---Xml file from assets folder---
InputStream input_Stream = context.getApplicationContext().getAssets().open("sample.xml");
xmlPullParserObject.setInput(input_Stream, null);

//---while---

while (xmlPullParserObject.getEventType() != XmlPullParser.END_DOCUMENT) {

//---Create Array---
arrayCategory = new String[counter];

if (xmlPullParserObject.getEventType() == XmlPullParser.START_TAG &&
xmlPullParserObject.getName().equals("button")) {
arrayCategory[counter] = xmlPullParserObject.getAttributeValue(1);
counter++;
}
xmlPullParserObject.next();
}

} catch (Exception e) {
e.printStackTrace();
}
}

public String[] getAllCats(){

return arrayCategory;
}
}


من فایل xml و داخل فولدر assets قرار دادم.

و این هم کلاس اصلی برنامه.


import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.widget.Button;
import android.widget.LinearLayout;


public class MainActivity extends Activity {

Context context;

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

//---Create instance from Category---
String[] returnCatsArrayString = new Category(this).getAllCats();

LinearLayout li = (LinearLayout) findViewById(R.id.li);

for (int i = 0; i < returnCatsArrayString.length; i++) {

Button btn = new Button(this);
li.addView(btn);
btn.setText(returnCatsArrayString[i]);
}
}
}


من یه بار این آرایه رو "returnCatsArrayString" به String کست کردم و اون مقدار و برای مقدار دادن نام به دکمه ها گذاشتم. حلقه for اجرا شد ولی تمام اسماش و null بود.
بعضی از دوستان راهنمایی کردن گفتن شاید فایل xml و درست پارس نمی کنه و آرایه های هیچ مقداری و ندارن. ولی به نظر خودم درست نوشتم.
ممنون از همه.

poorman
دوشنبه 30 تیر 1393, 22:23 عصر
مشکل شما الان اینه که توی حلقه while دارید هر بار آرایه رو مجدد فضا میدید و جدید تعریفش میکنید

این در حالیه که دارید بر اساس counter این فضا رو اختصاص میدید که مقدارش در اولین بار صفر هست

آرایه رو قبل از حلقه جدید تعریف کنید و یک اندازه مشخص بدید بهش

کد اکتیویتی شما هیچ مشکلی نداره، فقط مشکلتون توی پارس کردن و ریختن داخل آرایه هست