روش ساخت ویکی Wiki ( چطور میشه یک یا چند کلمه در متن رو به شکل لینک در آورد مثل ویکی ها&n ...
سلام دوستان یک برنامه دارم که میخام بعضی کلمات رو لینک کنم و وقتی روی اونها کلیک میشه بره تو صفحه مربوطه راهش چیه ممنون .
این روش هم هست :
TextView tv = (TextView) findViewById(R.id.textView);
SpannableString text = new SpannableString(
"این سرویس صرفاً برای این سایت و توسط مدیریت سایت - بهنام آقاجانی ، برنامه نویسی شده است");
ClickableSpan clickfor = new ClickableSpan() {
@Override
public void onClick(View widget) {
Toast.makeText(widget.getContext(), "دانش آموخته از : دانشگاه آزاد اسلامي – واحد تهران مركز",
Toast.LENGTH_LONG).show();
}
};
text.setSpan(new URLSpan("http://uncocoder.com/"), 25,
29, 0);
text.setSpan(clickfor, 51, 64, 0);
tv.setMovementMethod(LinkMovementMethod.getInstance());
tv.setText(text, BufferType.SPANNABLE);
متنی رو که میخای رو توی یک TextView بزار و برای اون تکست ویو SetOnClickListener تعریف کن بصورت زیر
من از این روش استفاده کردم
txturl.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Intent myWebLink = new Intent(android.content.Intent.ACTION_VIEW);
myWebLink.setData(Uri.parse("http://answers.uncocoder.com/user/profile/2385"));
startActivity(myWebLink);
}
});
جواب S P ! R ! T عزیز مناسب و کامله - بهر حال یه سمپل هم میزارم
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView textView=(TextView) findViewById(R.id.textView);
String term = "لینک";
String content = "سلام این یه لینکه که وسط متن ما اومده ! به افتخار این لینک وسط متن ما";
final Pattern p = Pattern.compile(term);
final Matcher matcher = p.matcher(content);
final SpannableStringBuilder spannable = new SpannableStringBuilder(content);
while (matcher.find()) {
spannable.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
Toast.makeText(MainActivity.this, "لینکه کلیک شد!", Toast.LENGTH_LONG).show();
Log.i("PG","لینکه کلیک شد!");
}
},
matcher.start(), matcher.end(),
0);
}
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setText(spannable,TextView.BufferType.SPANNABLE);
}
}
محمد جان خیلی ممنون از جواب خوبت . ولی سوال اینجاست که من چطور یک کلمه داخل یک فایل وردی رو لینک کنم ؟
ببین در کد من nokat استرینگی هست که فایل وردی درش کپی شده.و این متن میخاد در txtmatn نمایش داده بشه . حالا در متن اون استرینگ بعضی از کلمات لینک باید بشن . حالا چه کار باید بکنم ؟
سوال دوم هم اینه که اون override سومی و inflate و ...که با ایجاد فایل جدید ایجاد میشه به چه درد میخوره ؟ ما اصلا تا آخر پروژه باهاش کار داریم یا نه ؟
ممنون از وتی که میزاری !
public class ActivityNokat extends Activity {
@Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
Intent intent = new Intent(ActivityNokat.this, ActivityIndex.class);
ActivityNokat.this.startActivity(intent);
ActivityNokat.this.finish();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.matn);
TextView txtmatn = (TextView) findViewById(R.id.txtmatn);
txtmatn.setText(getString(R.string.nokat));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
آقا یافتم من به این صورت حلش کردم الحمدلله. میزارم تا آیندگان استفاده کنند ساخت ویکی مدتها فکرم رو مشغول کرده بود اصلا فکرش رو نمیکردم توی ۱۰ دقیقه حل بشه . بازم ممنون از دوستان و spirit و بخصوص محمد عزیز .اما یک سوال دیگه هم پیش میاد که اگر ما چند عبارت رو بخایم لینک کنیم و مثلا term2 ,term3 ... چطور باید بنویسیم چون قبول نمیکنه که با هم در یک پرانتز باشند در
final Pattern p = Pattern.compile(term,term2,term3);
و اما جواب سوال دوم هنوز مجهوله .
@Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
Intent intent = new Intent(ActivityNokat.this, ActivityIndex.class);
ActivityNokat.this.startActivity(intent);
ActivityNokat.this.finish();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.matn);
TextView txtmatn = (TextView) findViewById(R.id.txtmatn);
//txtmatn.setText(getString(R.string.nokat));
//TextView textView=(TextView) findViewById(R.id.textView);
String term = "مهم";
String content = getString(R.string.nokat);
final Pattern p = Pattern.compile(term);
final Matcher matcher = p.matcher(content);
final SpannableStringBuilder spannable = new SpannableStringBuilder(content);
while (matcher.find()) {
spannable.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
Toast.makeText(ActivityNokat.this, "لینکه کلیک شد!", Toast.LENGTH_LONG).show();
Log.i("PG","لینکه کلیک شد!");
}
},
matcher.start(), matcher.end(),
0);
}
txtmatn.setMovementMethod(LinkMovementMethod.getInstance());
txtmatn.setText(spannable,TextView.BufferType.SPANNABLE);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
مهدی جان در مورد چند واژه پرسیده بودی - راهکار باز هم همینه
پیاده سازی دیگه به خودت بر میگرده - میخوای همه کلمات توی متنت لینک بشن - آیتم خاصی لینک بشه و ...
کد زیر رو تست کنی و با قبلی قیاس کنی تقریبا دستت میاد باید چه کنی
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView textView = (TextView) findViewById(R.id.textView);
Map<String, String> wikiItems = new HashMap<String, String>();
wikiItems.put("لینک", "لینک--");
wikiItems.put("متن", "متن--");
wikiItems.put("وسط", "وسط--");
String content = "سلام این یه لینکه که وسط متن ما اومده ! به افتخار این لینک وسط متن ما";
final SpannableStringBuilder spannable = new SpannableStringBuilder(content);
Iterator<Map.Entry<String, String>> it = wikiItems.entrySet().iterator();
while (it.hasNext()) {
final Map.Entry<String, String> entry = it.next();
int startIndex = content.indexOf(entry.getKey());
if (startIndex == -1) continue;
spannable.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
Toast.makeText(MainActivity.this, entry.getValue(), Toast.LENGTH_LONG).show();
}
},
startIndex, startIndex + entry.getKey().length(),
0);
}
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setText(spannable, TextView.BufferType.SPANNABLE);
}
}
ضمن تشکر از همه دوستان بحث ساخت ویکی داره کامل میشه .
من کد رو وارد کردم و درست هم کار میکنه ولی مشکل اینجاست که اگر بخاهیم به جای toast در آن کلیک بنویسیم که با تاچ هر عبارت صفحه مربوط به همون عبارت باز بشه و مقدار معادلش که قبلا تعریف کردیم به نمایش در بیاد چجور باید بنویسیم ؟ من سعی کردم تا جا های خوبی هم رسیدم ولی کامل نشد کد رو میزارم براتون :
public class ActivityRizesh extends Activity {
@Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
Intent intent = new Intent(ActivityRizesh.this, ActivityIndex.class);
ActivityRizesh.this.startActivity(intent);
ActivityRizesh.this.finish();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.matn);
final TextView txtmatn = (TextView) findViewById(R.id.txtmatn);
Map<String, String> wikiItems = new HashMap<String, String>();
wikiItems.put("لینک", "متن معادل لینک");
wikiItems.put("متن", "متن معادل متن");
wikiItems.put("وسط", "متن معادل وسط");
String content = "سلام این یه لینکه که وسط متن ما اومده ! به افتخار این لینک وسط متن ما";
final SpannableStringBuilder spannable = new SpannableStringBuilder(content);
Iterator<Map.Entry<String, String>> it = wikiItems.entrySet().iterator();
while (it.hasNext()) {
final Map.Entry<String, String> entry = it.next();
int startIndex = content.indexOf(entry.getKey());
if (startIndex == -1) continue;
spannable.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
//Toast.makeText(ActivityRizesh.this, entry.getValue(), Toast.LENGTH_LONG).show();
Intent intent = new Intent(ActivityRizesh.this, ActivityMatn.class);
ActivityRizesh.this.startActivity(intent);
ActivityRizesh.this.finish();
}
},
startIndex, startIndex + entry.getKey().length(),
0);
}
txtmatn.setMovementMethod(LinkMovementMethod.getInstance());
txtmatn.setText(spannable, TextView.BufferType.SPANNABLE);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
حالا در ActivityMatn با کد زیر نمیدونم چطور اون متن های معادل رو که در پرانتز ها آوردم باید صدا بزنم ولی این به ذهنم رسی که اگر متد entry.getValue() به صورت استاتیک نوشته بشه میشه اینجا صداش کرد و حل میشه :
public class ActivityMatn extends Activity {
@Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
Intent intent = new Intent(ActivityMatn.this, ActivityIndex.class);
ActivityMatn.this.startActivity(intent);
ActivityMatn.this.finish();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.matn);
TextView txtmatn = (TextView) findViewById(R.id.txtmatn);
txtmatn.settext(entry.getValue());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
اما در مورد راه حل پست قبلی که خیلی ساده تر بود من با تکرار همون پروسه لینک کردن فقط یک کلمه خواستم که برای هر کلمه ای کد مجزا بنویسم اما نتیجه این شد که فقط یکی از کد ها رو ترتیب اثر داد ولینک کرد اینم کد مشکل چیه حالا؟
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.matn);
final TextView txtmatn = (TextView) findViewById(R.id.txtmatn);
//txtmatn.setText(getString(R.string.khoshki));
//TextView textView=(TextView) findViewById(R.id.textView);
String term = "قرص ویتامین";
String content = getString(R.string.rizesh);
final Pattern p = Pattern.compile(term);
final Matcher matcher = p.matcher(content);
final SpannableStringBuilder spannable = new SpannableStringBuilder(content);
while (matcher.find()) {
spannable.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
Toast.makeText(ActivityRizesh.this, "لینکه کلیک شد!", Toast.LENGTH_LONG).show();
Log.i("PG","لینکه کلیک شد!");
}
},
matcher.start(), matcher.end(),
0);
}
txtmatn.setMovementMethod(LinkMovementMethod.getInstance());
txtmatn.setText(spannable,TextView.BufferType.SPANNABLE);
String term2 = "عصاره ";
String content2 = getString(R.string.rizesh);
final Pattern p2 = Pattern.compile(term2);
final Matcher matcher2 = p2.matcher(content2);
final SpannableStringBuilder spannable2 = new SpannableStringBuilder(content2);
while (matcher2.find()) {
spannable2.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
Toast.makeText(ActivityRizesh.this, "لینکه کلیک شد!", Toast.LENGTH_LONG).show();
Log.i("PG","لینکه کلیک شد!");
}
},
matcher2.start(), matcher2.end(),
0);
}
ضمن تشکر از Sp!R!T عزیز که وقت میزاره من کد رو اصلاح کردم یعنی settext رو اضافه کردم ولی نمیدونم چطوری باید خروجی فرآیند اول رو به فرآیند دوم بدم و در آخر بدم به TextView البته سعی کردم این کار رو بکنم و همه رو جمع کنم در Allspannables ولی ارور میده حالا راهش چیه ؟ ممنون
final TextView txtmatn = (TextView) findViewById(R.id.txtmatn);
//txtmatn.setText(getString(R.string.khoshki));
//TextView textView=(TextView) findViewById(R.id.textView);
String term = "قرص ویتامین";
String content = getString(R.string.rizesh);
final Pattern p = Pattern.compile(term);
final Matcher matcher = p.matcher(content);
final SpannableStringBuilder spannable = new SpannableStringBuilder(content);
while (matcher.find()) {
spannable.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
Toast.makeText(ActivityRizesh.this, "لینکه کلیک شد!", Toast.LENGTH_LONG).show();
Log.i("PG","لینکه کلیک شد!");
}
},
matcher.start(), matcher.end(),
0);
}
txtmatn.setMovementMethod(LinkMovementMethod.getInstance());
// txtmatn.setText(spannable,TextView.BufferType.SPANNABLE);
String term2 = "عصاره ";
String content2 = getString(R.string.rizesh);
final Pattern p2 = Pattern.compile(term2);
final Matcher matcher2 = p2.matcher(content2);
final SpannableStringBuilder spannable2 = new SpannableStringBuilder(content2);
while (matcher2.find()) {
spannable2.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
Toast.makeText(ActivityRizesh.this, "لینکه کلیک شد!", Toast.LENGTH_LONG).show();
Log.i("PG","لینکه کلیک شد!");
}
},
matcher2.start(), matcher2.end(),
0);
}
txtmatn.setMovementMethod(LinkMovementMethod.getInstance());
//txtmatn.setText(spannable2,TextView.BufferType.SPANNABLE);
/////////////
String term3 = "معجون";
String content3 = getString(R.string.rizesh);
final Pattern p3 = Pattern.compile(term3);
final Matcher matcher3 = p3.matcher(content3);
final SpannableStringBuilder spannable3 = new SpannableStringBuilder(content3);
while (matcher3.find()) {
spannable3.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
Toast.makeText(ActivityRizesh.this, "لینکه کلیک شد!", Toast.LENGTH_LONG).show();
Log.i("PG","لینکه کلیک شد!");
}
},
matcher3.start(), matcher3.end(),
0);
}
txtmatn.setMovementMethod(LinkMovementMethod.getInstance());
////////////////////
AllSpannables = spannable + spannable2 + spannable3;
txtmatn.setText(AllSpannables,TextView.BufferType.SPANNABLE);
چون کدهای بالا درست نشون داده نشد یک بار دیگه ۲ تا راه دیگه رو هم که برای جمع کردن ۳ تاشون در یک تکست ویو رفتم مینویسم که البته ناموفق بود بازم .
String AllSpannables = spannable +""+ spannable2 + spannable3;
txtmatn.setText(AllSpannables,TextView.BufferType.SPANNABLE);
و یا
//String AllSpannables = spannable +""+ spannable2 + spannable3;
txtmatn.setText(spannable +""+ spannable2 + spannable3,TextView.BufferType.SPANNABLE);
خوب با تشکر از دوستان . بعد از کلی انتظار کشیدن نه چندان مفید و بعدش کلنجار رفتن با کد از طریق شیوه آزمون و خطا و کمک های قبلی دوستان تونستم حلش کنم الحمدلله و الان دیگه خیلی نزدیک شده به شکل نهایی خودش فقط یک مشکلی هست و اون اینکه چون هر کاری کردم نتونستم با کلیک بر روی یک کلمه یک اکتیویتی جدا باز کنم ( یعنی کاری نداره ولی مشکل اینه که در اکتیویتی جدید همونطور که قبلا هم بالاتر نوشتم نمیدونم چطور میشه متن متناظر لینک رو در داخل تکست ویو انداخت) در نتیجه اومدم تکست ویوی همون صفحه ای که داخلش هستیم رو بدون اینکه یک صفحه جدید باز بشه دوباره ست تکست کردم . اینجا مشکل حل میشه ولی در برگشت با دکمه بک مکانیکی به مشکل بر میخوریم یعنی به دو مرحله قبل بر میگرده . اگر کسی بتونه راهنمایی کنه که چطوری من این دستور txtmatn.setText(entry.getValue()); رو در اکتیویتیه جدیدی که برای اون لینک باز میشه ست تکست کنم (چون در حالت معمول قبول نمیکنه ولی به نظرم اگر استاتیک نوشته بشه قابل صدا زدنه ولی من بلد نیستم چطوری! ) کلا مشکل من و هر کس دیگه ای که بعدا میاد حل میشه فقط اینکه بشه اون رو از اکتیویتی لینکها صدا زد . ممنون .
public class ActivityRizesh extends Activity {
@Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
Intent intent = new Intent(ActivityRizesh.this, ActivityRizesh.class);
ActivityRizesh.this.startActivity(intent);
ActivityRizesh.this.finish();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.matn);
final TextView txtmatn = (TextView) findViewById(R.id.txtmatn);
final TextView txtback = (TextView) findViewById(R.id.txtback);
Map<String, String> wikiItems = new HashMap<String, String>();
wikiItems.put("لینک", "متن معادل لینک");
wikiItems.put("متن", "متن معادل متن");
wikiItems.put("وسط", "متن معادل وسط");
String content = "سلام این یه لینکه که وسط متن ما اومده ! به افتخار این لینک وسط متن ما";
final SpannableStringBuilder spannable = new SpannableStringBuilder(content);
Iterator<Map.Entry<String, String>> it = wikiItems.entrySet().iterator();
while (it.hasNext()) {
final Map.Entry<String, String> entry = it.next();
int startIndex = content.indexOf(entry.getKey());
if (startIndex == -1) continue;
spannable.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
txtmatn.setText(entry.getValue());
}
},
startIndex, startIndex + entry.getKey().length(),
0);
}
txtmatn.setMovementMethod(LinkMovementMethod.getInstance());
txtmatn.setText(spannable, TextView.BufferType.SPANNABLE);
txtback.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent(ActivityRizesh.this, ActivityIndex.class);
ActivityRizesh.this.startActivity(intent);
ActivityRizesh.this.finish();
}
});
}
}
برای جلوگیری از دست به دامن استاتیک شدن میشه از یه دیالوگ استفاده کرد، البته امکانش به شرایط برنامه بر میگرده
کد مناسب دیالوگ برای اکتیویتی :
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView textView = (TextView) findViewById(R.id.textView);
final WikiDialog wikiDialog = new WikiDialog(this);
Map<String, String> wikiItems = new HashMap<String, String>();
wikiItems.put("لینک", "لینک---");
wikiItems.put("متن", "متن--");
wikiItems.put("وسط", "وسط--");
String content = "سلام این یه لینکه که وسط متن ما اومده ! به افتخار این لینک وسط متن ما";
final SpannableStringBuilder spannable = new SpannableStringBuilder(content);
Iterator<Map.Entry<String, String>> it = wikiItems.entrySet().iterator();
while (it.hasNext()) {
final Map.Entry<String, String> entry = it.next();
int startIndex = content.indexOf(entry.getKey());
while (startIndex != -1) {
spannable.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
wikiDialog.init(entry.getValue());
}
}, startIndex, startIndex + entry.getKey().length(), 0);
startIndex = content.indexOf(entry.getKey(), startIndex + 1);
}
}
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setText(spannable, TextView.BufferType.SPANNABLE);
}
}
تو کد بالا از یه دیالوگ سفارشی استفاده شده که عنوان نداره - یه دکمه برای بستنش هست - محتویاتش اسکرول میشه , متنش قابل تغییره :
public class WikiDialog extends Dialog {
private TextView textView;
public WikiDialog(Context context) {
super(context);
initialize();
}
public WikiDialog(Context context, int theme) {
super(context, theme);
initialize();
}
protected WikiDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
super(context, cancelable, cancelListener);
initialize();
}
private void initialize() {
setCanceledOnTouchOutside(true);
textView = new TextView(G.context);
textView.setGravity(Gravity.CENTER);
textView.setTextColor(Color.BLACK);
textView.setLineSpacing(0, 1.5F);
Button button = new Button(G.context);
button.setText("بازگشت");
button.setTextColor(Color.WHITE);
button.setBackgroundColor(Color.GRAY);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
LinearLayout linearLayout = new LinearLayout(G.context);
linearLayout.setOrientation(LinearLayout.VERTICAL);
linearLayout.addView(textView);
linearLayout.addView(button);
linearLayout.setGravity(Gravity.CENTER);
ScrollView scrollView=new ScrollView(G.context);
scrollView.setPadding(30, 30, 30, 30);
scrollView.addView(linearLayout);
scrollView.setBackgroundColor(Color.WHITE);
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
setContentView(scrollView);
}
public void init(String text) {
textView.setText(text);
show();
}
}
پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .