日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android Textview 一行居中 两行居左

發(fā)布時間:2023/12/20 Android 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android Textview 一行居中 两行居左 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

需求描述:

  • 采用鴻洋大神打造的萬能的ListView GridView適配器;
  • ListView中的item中有一個TextView,該TextView的寬度確定,根據(jù)要顯示的內(nèi)容長度動態(tài)調(diào)整文字的顯示方式:不超過1行居中顯示;超過1行的話無論第二行有幾個字,左對齊顯示。效果圖如下所示(這里只找到了居中的示例):
  • 剛開始寫的item布局文件如下:

    <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/fl_root"android:layout_width="wrap_content"android:layout_height="wrap_content"><RoundedImageViewandroid:id="@+id/iv_image"android:layout_width="match_parent"android:layout_height="match_parent"android:scaleType="centerCrop"android:src="@drawable/friendshipislandbg4"android:riv_border_width="0dp"android:riv_corner_radius="8dp" /><TextViewandroid:id="@+id/tv_name"android:layout_width="match_parent"android:layout_height="50dp"android:layout_gravity="bottom"android:background="@drawable/bs_school_name_bg"android:gravity="center"android:maxLines="2"android:paddingLeft="20dp"android:paddingRight="20dp"android:textColor="#ffffff"android:textSize="16sp" /></FrameLayout> 復(fù)制代碼

    動態(tài)代碼調(diào)整TextView的Gravity代碼如下:

    @Overridepublic void convert(ListviewViewHolder holder, TempDataBean item) {FrameLayout flRoot = (FrameLayout) holder.getView(R.id.fl_root);//動態(tài)調(diào)整GridView中每一個item的大小,防止圖片大小不同導(dǎo)致每一個item的大小不同ViewGroup.LayoutParams params = flRoot.getLayoutParams();params.height = displayWidth / 2 - MyUtils.dip2px(ctx, 18);params.width = displayWidth / 2 - MyUtils.dip2px(ctx, 18);flRoot.setLayoutParams(params);flRoot.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {startActivity(new Intent(BSItemActivity.this, BSDetailActivity.class));}});//顯示圖片mImageLoader.displayImage(item.getSchoolImage(), (ImageView) holder.getView(R.id.iv_school_image), options, mImageLoadingListener);//用來判斷是學(xué)校名字是一行或者兩行holder.setText(R.id.tv_name, item.getName());TextView tv = (TextView) holder.getView(R.id.tv_name);int lineCount = tv.getLineCount();if(lineCount<=1){// 1行居中tv.setGravity(Gravity.CENTER);}else{// 2行居左tv.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);}} 復(fù)制代碼

    編譯,安裝,跑起來,發(fā)現(xiàn)并不是預(yù)期的效果。現(xiàn)在的效果是第一次進(jìn)入頁面,未滑動,無論是一行還是兩行都是居中顯示。將第一屏滑出界面,并再次滑入界面的時候,1行的居中,2行的居左(符合預(yù)期)。我擦,這是什么情況。帶著疑問,我將懷疑的目光轉(zhuǎn)向了大神造的輪子。

    public static ListviewViewHolder get(Context context, View convertView, ViewGroup parent, int layoutId, int position) {if (convertView == null) {View itemView = LayoutInflater.from(context).inflate(layoutId, parent,false);ListviewViewHolder holder = new ListviewViewHolder(context, itemView, parent, position);holder.mLayoutId = layoutId;return holder;} else {ListviewViewHolder holder = (ListviewViewHolder) convertView.getTag();holder.mPosttion = position;return holder;} } 復(fù)制代碼

    我懷疑這段代碼是不是少了一些東西,大神沒有考慮到可能會有動態(tài)修改布局的操作,而僅僅在public void convert(ListviewViewHolder holder, TempDataBean item)方法中考慮了數(shù)據(jù)替換的操作。

    我又懷疑是不是使用LayoutInflater填充出來的View和復(fù)用的convertView有一些不同。難道應(yīng)該在使用LayoutInflater進(jìn)行填充View的時候就進(jìn)行動態(tài)修改布局的操作,對復(fù)用的convertView修改布局參數(shù)莫非晚了?說干就干,我就寫了一個抽象類,在使用LayoutInflater填充出View之后立即對View進(jìn)行修改布局操作。抽象類如下:

    public abstract class SetLayoutProperty {View itemView;int position;//獲得填充出來的View及對應(yīng)的位置public void setItemView(View itemView, int position) {this.itemView = itemView;this.position = position;}//動態(tài)改變布局參數(shù)的具體操作public abstract void setLayoutProperty();public View getItemView() {return this.itemView;}public int getPosition() {return position;} } 復(fù)制代碼

    然后修改了大神造的ViewHolder如下:

    public static ListviewViewHolder get(Context context, View convertView, ViewGroup parent, int layoutId, int position,SetLayoutProperty setLayoutProperty) {if (convertView == null) {View itemView = LayoutInflater.from(context).inflate(layoutId, parent,false);//主要增加了這個語句塊if (setLayoutProperty != null) {setLayoutProperty.setItemView(itemView,position);setLayoutProperty.setLayoutProperty();}ListviewViewHolder holder = new ListviewViewHolder(context, itemView, parent, position);holder.mLayoutId = layoutId;return holder;} else {ListviewViewHolder holder = (ListviewViewHolder) convertView.getTag();holder.mPosttion = position;return holder;} } 復(fù)制代碼

    由代碼可以看出,如果抽象類不為空,說明具體操作實(shí)現(xiàn)了這個抽象類,調(diào)用setLayoutProperty.setItemView(itemView,position)方法將需要的內(nèi)容傳出,調(diào)用setLayoutProperty.setLayoutProperty()方法將執(zhí)行具體的修改布局參數(shù)的邏輯。

    又修改了大神造的Adapter如下:

    /*** 在復(fù)用之前(展示之前)對一些布局參數(shù)進(jìn)行調(diào)整** @return*/ public SetLayoutProperty setLayoutProperty() {return null; } 復(fù)制代碼

    使用輪子的時候我選擇這樣寫:

    @Overridepublic SetLayoutProperty setLayoutProperty() {return new SetLayoutProperty() {@Overridepublic void setLayoutProperty() {//獲取條目布局View itemView = this.getItemView();TextView tv = (TextView) itemView.findViewById(R.id.tv_school_name);tv.setText(datas.get(getPosition()).getSchoolName());int lineCount = tv.getLineCount();LogSwitchUtils.logD(BSItemActivity.class,"學(xué)校名字的內(nèi)容為:"+datas.get(getPosition()).getSchoolName());LogSwitchUtils.logD(BSItemActivity.class,"學(xué)校名字的行數(shù)為:"+lineCount);if (lineCount <= 1) {tv.setGravity(Gravity.CENTER);} else {tv.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);}}};}@Overridepublic void convert(ListviewViewHolder holder, TempDataBean item) {...} 復(fù)制代碼

    效果是:無論是否滑出或者滑入,無論是1行還是2行,都是居中顯示。 通過打印的日志,我發(fā)現(xiàn)通過getLineCount()方法獲得的數(shù)值都為0。不應(yīng)該啊,讓我看看這個方法,于是就發(fā)現(xiàn):

    /*** Return the number of lines of text, or 0 if the internal Layout has not* been built.*/ public int getLineCount() {return mLayout != null ? mLayout.getLineCount() : 0; } 復(fù)制代碼

    我了個去,此時此刻我只想知道如何讓 The internal Layout has been built.或者什么時候The internal Layout has been built.

    于是乎,我就找度娘,我給度娘說:Return the number of lines of text, or 0 if the internal Layout has not been built.然后度娘沒有告訴我想要的答案:即如何讓?或者什么時候?

    我又接著問度娘:“getlinecount一直是0?”

    度娘說了:TextView可以通過getLineCount獲取行數(shù),但是這里要在控件繪畫后才能獲取,否則調(diào)用這個函數(shù)返回值為0。但是我想在addText時就獲得text的行數(shù),這樣我可以控制TextView的高度,請問有沒有一些開源的代碼或者想法可以實(shí)現(xiàn)在addText獲取行數(shù)呢?

    哈哈哈哈....在知乎我知道了什么時候獲取行數(shù)不為0,代碼如下。

    final TextView totalTitleNo = (TextView) findViewById(R.id.tv_ac_sub_account); ViewTreeObserver vto = totalTitleNo.getViewTreeObserver(); vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {@Overridepublic boolean onPreDraw() {int lineCount = totalTitleNo.getLineCount();System.out.println(lineCount);} }); 復(fù)制代碼

    迫不及待,我趕緊試試:

    @Overridepublic void convert(ListviewViewHolder holder, TempDataBean item) {FrameLayout flRoot = (FrameLayout) holder.getView(R.id.root_fl);ViewGroup.LayoutParams params = flRoot.getLayoutParams();params.height = displayWidth / 2 - MyUtils.dip2px(ctx, 18);params.width = displayWidth / 2 - MyUtils.dip2px(ctx, 18);flRoot.setLayoutParams(params);flRoot.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {startActivity(new Intent(BSItemActivity.this, BSDetailActivity.class));}});//顯示圖片mImageLoader.displayImage(item.getSchoolImage(), (ImageView) holder.getView(R.id.iv_school_image), options, mImageLoadingListener);//為測試的控件設(shè)置值,用來判斷是學(xué)校名字是一行或者兩行holder.setText(R.id.tv_school_name, item.getSchoolName());final TextView tv = (TextView) holder.getView(R.id.tv_school_name);ViewTreeObserver vto = tv.getViewTreeObserver();//這個監(jiān)聽器看名字也知道了,就是在繪畫完成之前調(diào)用的,在這里面可以獲取到行數(shù),當(dāng)然也可以獲取到寬高等信息。vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {@Overridepublic boolean onPreDraw() {int lineCount = tv.getLineCount();LogSwitchUtils.logD(BSItemActivity.class, "學(xué)校名字的行數(shù)為:" + lineCount);if (lineCount <= 1) {tv.setGravity(Gravity.CENTER);//tv.invalidate();} else {tv.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);//tv.invalidate();}return true;}});} 復(fù)制代碼

    一開始,我的最后一句代碼是return false;但發(fā)現(xiàn)不行,該界面顯示不出來但一直打Log,于是就選擇返回了true。

    一開始,最后一個注釋其實(shí)并不是注釋,但是當(dāng)我將它注釋掉,發(fā)現(xiàn)結(jié)果依然是正確的,它就成了注釋。

    在解決問題的時候,我還問過度娘:android Textview 一行居中,兩行居左?

    檢索度娘得到了如下使用布局文件使TextView實(shí)現(xiàn)一行居中,兩行居左的效果:

    <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/root_fl"android:layout_width="wrap_content"android:layout_height="wrap_content"><com.makeramen.roundedimageview.RoundedImageViewandroid:id="@+id/iv_school_image"android:layout_width="match_parent"android:layout_height="match_parent"android:scaleType="centerCrop"android:src="@drawable/friendshipislandbg4"app:riv_border_width="0dp"app:riv_corner_radius="8dp" />//該層使文字顯示在底部<RelativeLayoutandroid:layout_width="match_parent"android:layout_height="50dp"android:background="@drawable/bs_school_name_bg"android:layout_gravity="bottom"><LinearLayout//該層使單行居中android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:orientation="vertical"><TextView//該層使兩行居左android:paddingLeft="20dp"android:paddingRight="20dp"android:id="@+id/tv_school_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:gravity="left"android:maxLines="2"android:textColor="#ffffff"android:textSize="16sp" /></LinearLayout></RelativeLayout></FrameLayout> 復(fù)制代碼

    至此,實(shí)現(xiàn)【Android Textview 一行居中 兩行居左】需求時我的所想,所做,所得都記錄在了這里,便于以后復(fù)習(xí)。

    結(jié)論

  • 大神造的輪子沒有錯,是自己的理解有錯。但敢于向權(quán)威質(zhì)疑的精神是對的,在修改輪子的時候,順便練習(xí)了使用抽象類和接口的使用;
  • 實(shí)現(xiàn)TextView的單行居中,兩行居左方法有:動態(tài)調(diào)整布局參數(shù);完善布局文件;
  • 深刻體會了textview.getLineCount()方法。
  • 總結(jié)

    以上是生活随笔為你收集整理的Android Textview 一行居中 两行居左的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。