هل هناك طريقة لجعل ellipsize = "سرادق" انتقل دائما؟
سؤال
أريد استخدام تأثير سرادق على نص نصي، لكن النص يتم تمريره فقط عند التركيز النصي. هذه مشكلة، لأنه في حالتي، لا يمكن ذلك.
انا استخدم:
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
هل هناك طريقة لتمرير النص دائما نصها؟ لقد رأيت هذا يجري في تطبيق Android Market، حيث سيقوم اسم التطبيق بالتمرير في شريط العنوان، حتى لو لم يتلق التركيز، لكن لم أستطع العثور على ذلك المذكور في مستندات API.
المحلول
لقد واجهت المشكلة وأقصر الحل الذي وصلت إليه هو إنشاء فئة جديدة مشتقة من النص. يجب أن يتجاوز الفصل ثلاث طرق onfocuschanged., onwindowfocuschanged. و تركز لجعل النص يركز على النص.
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
if(focused)
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
@Override
public void onWindowFocusChanged(boolean focused) {
if(focused)
super.onWindowFocusChanged(focused);
}
@Override
public boolean isFocused() {
return true;
}
نصائح أخرى
لقد توصلت أخيرا إلى هذه المشكلة اليوم وأطلقت hierarchyviewer
على تطبيق سوق أندرويد.
النظر إلى العنوان على شاشة تفاصيل التطبيق، فإنها تستخدم القديم العادي TextView
. وبعد أظهر فحص ممتلكاتها أنه لم يركز، لا يمكن أن تركز وكان عموما عادي جدا - باستثناء حقيقة أنه تم وضع علامة عليه المحدد.
خط واحد من الكود في وقت لاحق وأنا كنت أعمل :)
textView.setSelected(true);
هذا منطقي، بالنظر إلى ما يقول جافادوك:
يمكن تحديد وجهة نظر أم لا. لاحظ أن التحديد ليس هو نفسه التركيز. يتم تحديد وجهات النظر عادة في سياق AdapterView مثل ListView أو GridView.
أي عند التمرير عبر عنصر في عرض قائمة (مثل في تطبيق السوق)، فقط ثم يفعل الآن اختيار نص بدء التمرير. ومنذ هذا بالذات TextView
غير قابل للترويج أو قابلة للنقر، فلن تفقد حالة اختيارها أبدا.
لسوء الحظ، بقدر ما أعرف أنه لا توجد طريقة لتعيين الحالة المحددة مسبقا من تخطيط XML.
لكن بطانة واحدة أعلاه يعمل بشكل جيد بالنسبة لي.
فقط ضع هذه المعلمات في النص. إنها تعمل :)
android:singleLine="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit ="marquee_forever"
android:scrollHorizontally="true"
android:focusable="true"
android:focusableInTouchMode="true"
TranslateAnimation
يعمل عن طريق "سحب" الرأي في اتجاه واحد بمقدار محدد. يمكنك ضبط مكان بدء هذا "السحب" وأين تنتهي.
TranslateAnimation(fromXDelta, toXDelta, fromYDelta, toYDelta);
قم بتوصيل Fresexdelta إزاحة موقع البداية للحركة في المحور X.
fromXDelta = 0 //no offset.
fromXDelta = 300 //the movement starts at 300px to the right.
fromXDelta = -300 //the movement starts at 300px to the left
يحدد ToxDelta موقف إزاحة إنهاء الحركة في المحور X.
toXDelta = 0 //no offset.
toXDelta = 300 //the movement ends at 300px to the right.
toXDelta = -300 //the movement ends at 300px to the left.
إذا كان عرض النص أكبر من أن الوحدة النمطية للفرق بين fresexdelta و Toxdelta، لن يتمكن النص من التحرك إلى Totalaly و Compeletely داخل الشاشة.
مثال
دعنا نفترض حجم الشاشة لدينا هو 320x240 PXS. لدينا نص نصي مع نص يحتوي على عرض 700px ونود إنشاء رسوم متحركة "تسحب" النص حتى نتمكن من رؤية نهاية العبارة.
(screen)
+---------------------------+
|<----------320px---------->|
| |
|+---------------------------<<<< X px >>>>
movement<-----|| some TextView with text that goes out...
|+---------------------------
| unconstrained size 700px |
| |
| |
+---------------------------+
+---------------------------+
| |
| |
<<<< X px >>>>---------------------------+|
movement<----- some TextView with text that goes out... ||
---------------------------+|
| |
| |
| |
+---------------------------+
أولا وضعنا fromXDelta = 0
بحيث لا تحتوي الحركة على إزاحة البدء. الآن نحتاج إلى معرفة قيمة تكسسوارات. لتحقيق التأثير المرغوب، نحتاج إلى "سحب" النص بالضبط نفس PX الذي يمضى من الشاشة. (في المخطط يمثله <<<<< X PX >>>>) نظرا لأن نصنا يحتوي على 700 عرض، والمنطقة المرئية هي 320 بكسل (عرض الشاشة) الذي حددناه:
tXDelta = 700 - 320 = 380
وكيف نستخدم عرض الشاشة وعرض النص؟
رمز
أخذ قشر الزراعة كنقطة انطلاق:
/**
* @param view The Textview or any other view we wish to apply the movement
* @param margin A margin to take into the calculation (since the view
* might have any siblings in the same "row")
*
**/
public static Animation scrollingText(View view, float margin){
Context context = view.getContext(); //gets the context of the view
// measures the unconstrained size of the view
// before it is drawn in the layout
view.measure(View.MeasureSpec.UNSPECIFIED,
View.MeasureSpec.UNSPECIFIED);
// takes the unconstrained wisth of the view
float width = view.getMeasuredWidth();
// gets the screen width
float screenWidth = ((Activity) context).getWindowManager().getDefaultDisplay().getWidth();
// perfrms the calculation
float toXDelta = width - (screenWidth - margin);
// sets toXDelta to 0 if the text width is smaller that the screen size
if (toXDelta < 0) {toXDelta = 0; } else { toXDelta = 0 - toXDelta;}
// Animation parameters
Animation mAnimation = new TranslateAnimation(0, toXDelta, 0, 0);
mAnimation.setDuration(15000);
mAnimation.setRepeatMode(Animation.RESTART);
mAnimation.setRepeatCount(Animation.INFINITE);
return mAnimation;
}
قد تكون هناك طرق أسهل لأداء هذا، ولكن هذا يعمل لكل عرض يمكنك التفكير فيه وهو قابل لإعادة الاستخدام. إنه مفيد خصيصا إذا كنت ترغب في تحريك نص نص في قائمة ListView دون كسر قدرات TextView ممكنة / OnFocus. كما أنه مخطوطات بشكل مستمر حتى لو لم يكن العرض مركزا.
لا أعرف إذا كنت لا تزال بحاجة إلى الإجابة، لكنني وجدت طريقة سهلة للقيام بذلك.
قم بإعداد الرسوم المتحركة الخاصة بك مثل ذلك:
Animation mAnimation = new TranslateAnimation(START_POS_X, END_POS_X,
START_POS_Y, END_POS_Y);
mAnimation.setDuration(TICKER_DURATION);
mAnimation.setRepeatMode(Animation.RESTART);
mAnimation.setRepeatCount(Animation.INFINITE);
START_POS_X
, END_POS_X
, START_POS_Y
و END_POS_Y
نكون float
القيم، في حين TICKER_DURATION
هو int
أعلنت مع ثوابتي الأخرى.
ثم يمكنك الآن تطبيق هذه الرسوم المتحركة على النص الخاص بك:
TextView tickerText = (TextView) findViewById(R.id.ticker);
tickerText.setAnimation(mAnimation);
وهذا كل شيء. :)
تبدأ الرسوم المتحركة الخاصة بي على الجانب الأيمن خارج الشاشة (300F) وينتهي على الجانب الأيسر خارج الشاشة (-300f)، مع مدة 15s (15000).
كتبت التعليمات البرمجية التالية لإجراء ListView مع عناصر نص سرادق. يعتمد على الحل الذي تم تحديده الموصوف أعلاه. في الأساس، أنا أقوم بتوسيع فئة الأقراص الزرائية وتجاوز طريقة GetView لتحديد النص قبل إرجاعها:
// Create an ArrayAdapter which selects its TextViews before returning
// them. This would enable marqueeing while still making the list item
// clickable.
class SelectingAdapter extends ArrayAdapter<LibraryItem>
{
public
SelectingAdapter(
Context context,
int resource,
int textViewResourceId,
LibraryItem[] objects
)
{
super(context, resource, textViewResourceId, objects);
}
@Override
public
View getView(int position, View convertView, ViewGroup parent)
{
View view = super.getView(position, convertView, parent);
TextView textview = (TextView) view.findViewById(
R.id.textview_playlist_item_title
);
textview.setSelected(true);
textview.setEnabled(true);
textview.setFocusable(false);
textview.setTextColor(0xffffffff);
return view;
}
}
هذه هي الحل الذي ينبثق في الجزء العلوي من بحث Google، لذلك اعتقدت أنني أستطيع نشر إجابة مفيدة هنا منذ أن أتعارض مع تذكر هذا في كثير من الأحيان إلى حد ما. على أي حال، يعمل هذا بالنسبة لي ويتطلب سمات XML و OnFocuschangelistener.
//XML
<TextView
android:id="@+id/blank_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:layout_gravity="center_horizontal|center_vertical"
android:background="#a4868585"
android:textColor="#fff"
android:textSize="15sp"
android:singleLine="true"
android:lines="1"
android:ellipsize="marquee"
android:marqueeRepeatLimit ="marquee_forever"
android:scrollHorizontally="true"
android:focusable="true"
android:focusableInTouchMode="true"
tools:ignore="Deprecated" />
//JAVA
titleText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
titleText.setSelected(true);
}
}
});
// XML
<TextView
android:id="@+id/tvMarque"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:layout_gravity="center_horizontal"
android:fadingEdge="horizontal"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:padding="5dp"
android:textSize="16sp"
android:text=""
android:textColor="@color/colorSyncText"
android:visibility="visible" />
// في جاوة
mtvMarque.setEllipsize(TextUtils.TruncateAt.MARQUEE);
mtvMarque.setSelected(true);
mtvMarque.setSingleLine(true);