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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

android动态设置textview的id,动态调整TextView的Gravity

發布時間:2024/3/12 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android动态设置textview的id,动态调整TextView的Gravity 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

需求:ListView中的item中有一個TextView,該TextView的寬度確定,根據要顯示的內容長度動態調整文字的顯示方式:不超過1行居中顯示;超過1行的話無論第二行有幾個字,左對齊顯示。

剛開始寫的item布局文件如下:

android:id="@+id/fl_root"

android:layout_width="wrap_content"

android:layout_height="wrap_content">

android: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" />

android: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" />

動態代碼調整TextView的Gravity代碼如下:

@Override

public void convert(ListviewViewHolder holder, TempDataBean item) {

FrameLayout flRoot = (FrameLayout) holder.getView(R.id.fl_root);

// 動態調整GridView中每一個item的大小,防止圖片大小不同導致每一個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() {

@Override

public 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);

//用來判斷是學校名字是一行或者兩行

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);

}

}

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

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;

}

}

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

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

public abstract class SetLayoutProperty {

View itemView;

int position;

//獲得填充出來的View及對應的位置

public void setItemView(View itemView, int position) {

this.itemView = itemView;

this.position = position;

}

//動態改變布局參數的具體操作

public abstract void setLayoutProperty();

public View getItemView() {

return this.itemView;

}

public int getPosition() {

return position;

}

}

然后修改了大神造的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;

}

}

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

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

/**

* 在復用之前(展示之前)對一些布局參數進行調整

*

* @return

*/

public SetLayoutProperty setLayoutProperty() {

return null;

}

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

@Override

public SetLayoutProperty setLayoutProperty() {

return new SetLayoutProperty() {

@Override

public 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,"學校名字的內容為:"+datas.get(getPosition()).getSchoolName());

LogSwitchUtils.logD(BSItemActivity.class,"學校名字的行數為:"+lineCount);

if (lineCount <= 1) {

tv.setGravity(Gravity.CENTER);

} else {

tv.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);

}

}

};

}

@Override

public void convert(ListviewViewHolder holder, TempDataBean item) {...}

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

/**

* 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;

}

我了個去,此時此刻我只想知道如何讓 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獲取行數,但是這里要在控件繪畫后才能獲取,否則調用這個函數返回值為0。但是我想在addText時就獲得text的行數,這樣我可以控制TextView的高度,請問有沒有一些開源的代碼或者想法可以實現在addText獲取行數呢?

哈哈哈哈....在這里我知道了什么時候?

并且找到了方法

final TextView totalTitleNo = (TextView) findViewById(R.id.tv_ac_sub_account);

ViewTreeObserver vto = totalTitleNo.getViewTreeObserver();

vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {

@Override

public boolean onPreDraw() {

int lineCount = totalTitleNo.getLineCount();

System.out.println(lineCount);

}

});

迫不及待,我趕緊試試:

@Override

public 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() {

@Override

public 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);

//為測試的控件設置值,用來判斷是學校名字是一行或者兩行

holder.setText(R.id.tv_school_name, item.getSchoolName());

final TextView tv = (TextView) holder.getView(R.id.tv_school_name);

ViewTreeObserver vto = tv.getViewTreeObserver();

//這個監聽器看名字也知道了,就是在繪畫完成之前調用的,在這里面可以獲取到行數,當然也可以獲取到寬高等信息。

vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {

@Override

public boolean onPreDraw() {

int lineCount = tv.getLineCount();

LogSwitchUtils.logD(BSItemActivity.class, "學校名字的行數為:" + lineCount);

if (lineCount <= 1) {

tv.setGravity(Gravity.CENTER);

//tv.invalidate();

} else {

tv.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);

//tv.invalidate();

}

return true;

}

});

}

一開始,我的最后一句代碼是return false;但發現不行,該界面顯示不出來,并且一直打Log,于是就返回了true。

一開始,最后一個注釋其實并不是注釋,但是當我將它注釋掉,發現結果依然是正確的,它就成了注釋。

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

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

xmlns:app="http://schemas.android.com/apk/res-auto"

android:id="@+id/root_fl"

android:layout_width="wrap_content"

android:layout_height="wrap_content">

android: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" />

//該層使文字顯示在底部

android:layout_width="match_parent"

android:layout_height="50dp"

android:background="@drawable/bs_school_name_bg"

android:layout_gravity="bottom">

//該層使單行居中

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerInParent="true"

android:orientation="vertical">

//該層使兩行居左

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" />

至此,解決一個問題我的所想,所做,所得都記錄在了這里,便于以后復習。

結論:

大神造的輪子沒有錯,是自己的理解有錯。但敢于向權威質疑的精神是對的,在修改輪子的時候,順便練習了使用抽象類和接口耦合高層模塊(抽象)與底層模塊(實現)的技術。

實現TextView的單行居中,兩行居左方法有:動態調整布局參數;完善布局文件。

深刻體會了tv.getLineCount()方法。

總結

以上是生活随笔為你收集整理的android动态设置textview的id,动态调整TextView的Gravity的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。