我需要显示所有参加指定 Activity 的用户个人资料图片,它应该在水平圆形图像中一张接一张,在 5 张图像之后。它应该显示剩余的用户总数。我需要 java 和 xml 文件。这些个人资料图像将来自数据库。请给我建议任何图书馆或一种方法
最佳答案
OverlapImageViewActivity.kt
class OverlapImageViewActivity : AppCompatActivity(), RecyclerViewClickListener {
private val mAdapter by lazy { OverlapRecyclerViewAdapter(this, this,overlapLimit) }
//------limit number of items to be overlapped
private val overlapLimit = 5
//------set value of item overlapping
private val overlapWidth = -50
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//------create dummy list to set on recycler view
setDummyArrayList()
//------set up recycler view
val layoutManager = LinearLayoutManager(this,
LinearLayoutManager.HORIZONTAL, false)
recyclerView.layoutManager = layoutManager
//------set item decoration for item overlapping
recyclerView.addItemDecoration(OverlapRecyclerViewDecoration(overlapLimit, overlapWidth))
recyclerView.adapter = mAdapter
mAdapter.setImageList(setDummyArrayList())
}
/**
* add dummy data to ArrayList
*/
private fun setDummyArrayList(): ArrayList<OverlapImageModel> {
val mArrayList = ArrayList<OverlapImageModel>()
//-----fill data in to array list
for (i in 0..30) {
val imageModel = OverlapImageModel()
imageModel.imageUrl = imageURLs[i % imageURLs.size]
mArrayList.add(imageModel)
}
return mArrayList
}
override fun onNormalItemClicked(adapterPosition: Int) {
toast(this,"Normal item clicked >> $adapterPosition")
}
override fun onNumberedItemClick(adapterPosition: Int) {
toast(this,"Numbered item clicked >> $adapterPosition")
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:orientation="vertical"
tools:context=".activities.OverlapImageViewActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingEnd="5dp"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
tools:listitem="@layout/row_image" />
</LinearLayout>
OverLapRecyclerViewAdapter.kt
class OverlapRecyclerViewAdapter(private var mContext: Context, private var recyclerViewClickListener: RecyclerViewClickListener
, private val overlapLimit: Int) : RecyclerView.Adapter<OverlapRecyclerViewAdapter.CustomViewHolder>() {
private val TAG = OverlapRecyclerViewAdapter::class.java.simpleName
//----array list to be shown
private var mImageList = ArrayList<OverlapImageModel>()
//----array list to be shown after expansion
private var mImageExpandedList = ArrayList<OverlapImageModel>()
//----flag to indicate recyclerview is expanded or not
private var isExpanded = false
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
val view = LayoutInflater.from(mContext).inflate(R.layout.row_image, parent, false)
return CustomViewHolder(view)
}
override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
val mCurrentImageModel = mImageList[position]
//----bind data to view
holder.bind(mCurrentImageModel)
}
/**
* set array list over adapter
*/
fun setImageList(mImageList: ArrayList<OverlapImageModel>) {
if (mImageList.size > overlapLimit) {
for (mImageModel in mImageList) {
if (this.mImageList.size <= overlapLimit) {
this.mImageList.add(mImageModel)
} else {
this.mImageExpandedList.add(mImageModel)
}
}
} else {
this.mImageList = mImageList
}
notifyDataSetChanged()
}
/**
* add items to array list
*/
fun addItems(mImageList: ArrayList<OverlapImageModel>) {
this.mImageList.addAll(mImageList)
notifyDataSetChanged()
}
override fun getItemCount(): Int {
return mImageList.size
}
/**
* get item by its position
*/
fun getItem(pos: Int): OverlapImageModel {
return mImageList[pos]
}
inner class CustomViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private var requestOptions: RequestOptions? = null
/**
* init request option for glide
*/
private fun getGlideRequestOptions(): RequestOptions {
if (requestOptions == null) {
requestOptions = RequestOptions()
requestOptions?.error(R.mipmap.ic_launcher)
requestOptions?.placeholder(R.mipmap.ic_launcher)
}
return requestOptions!!
}
/**
* bind model data to item
*/
fun bind(mImageModel: OverlapImageModel) {
if (adapterPosition == overlapLimit && !isExpanded) {
//----set text drawable to show count on last imageview
val text = mImageExpandedList.size.toString()
val drawable = TextDrawable.builder()
.beginConfig()
.textColor(Color.WHITE)
.width(90)
.height(90)
.endConfig()
.buildRound(text, Color.parseColor("#8FAE5D"))
itemView.imageView.setImageDrawable(drawable)
} else {
//----load image
Glide.with(mContext)
.load(mImageModel.imageUrl)
.apply(getGlideRequestOptions())
.into(itemView.imageView)
}
//----handle item click
itemView.imageView.setOnClickListener {
if (adapterPosition == overlapLimit && !isExpanded) {
recyclerViewClickListener.onNumberedItemClick(adapterPosition)
} else {
recyclerViewClickListener.onNormalItemClicked(adapterPosition)
}
}
}
}
}
OverlapRecyclerViewDecoration.kt
class OverlapRecyclerViewDecoration(private val overlapLimit: Int, private val overlapWidth: Int) : RecyclerView.ItemDecoration() {
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State?) {
//-----get current position of item
val itemPosition = parent.getChildAdapterPosition(view)
//-----avoid first item decoration else it will go of the screen
if (itemPosition == 0) {
return
} else {
//-----apply decoration
when {
itemPosition <= overlapLimit -> outRect.set(overlapWidth, 0, 0, 0)
else -> outRect.set(0, 0, 0, 0)
}
}
}
}
TextDrawable.kt
class TextDrawable(builder: Builder) : ShapeDrawable(builder.shape) {
private val textPaint: Paint
private val borderPaint: Paint
private val text: String?
private val color: Int
private val shape: RectShape?
private val height: Int
private val width: Int
private val fontSize: Int
private val radius: Float
private val borderThickness: Int
init {
// shape properties
shape = builder.shape
height = builder.height
width = builder.width
radius = builder.radius
// text and color
text = if (builder.toUpperCase) builder.text!!.toUpperCase() else builder.text
color = builder.color
// text paint settings
fontSize = builder.fontSize
textPaint = Paint()
textPaint.color = builder.textColor
textPaint.isAntiAlias = true
textPaint.isFakeBoldText = builder.isBold
textPaint.style = Paint.Style.FILL
textPaint.typeface = builder.font
textPaint.textAlign = Paint.Align.CENTER
textPaint.strokeWidth = builder.borderThickness.toFloat()
// border paint settings
borderThickness = builder.borderThickness
borderPaint = Paint()
borderPaint.color = getDarkerShade(builder.color)
borderPaint.style = Paint.Style.STROKE
borderPaint.strokeWidth = borderThickness.toFloat()
// drawable paint color
val paint = paint
paint.color = color
}
private fun getDarkerShade(color: Int): Int {
return Color.rgb((SHADE_FACTOR * Color.red(color)).toInt(),
(SHADE_FACTOR * Color.green(color)).toInt(),
(SHADE_FACTOR * Color.blue(color)).toInt())
}
override fun draw(canvas: Canvas) {
super.draw(canvas)
val r = bounds
// draw border
if (borderThickness > 0) {
drawBorder(canvas)
}
val count = canvas.save()
canvas.translate(r.left.toFloat(), r.top.toFloat())
// draw text
val width = if (this.width < 0) r.width() else this.width
val height = if (this.height < 0) r.height() else this.height
val fontSize = if (this.fontSize < 0) Math.min(width, height) / 2 else this.fontSize
textPaint.textSize = fontSize.toFloat()
canvas.drawText(text!!, (width / 2).toFloat(), height / 2 - (textPaint.descent() + textPaint.ascent()) / 2, textPaint)
canvas.restoreToCount(count)
}
private fun drawBorder(canvas: Canvas) {
val rect = RectF(bounds)
rect.inset((borderThickness / 2).toFloat(), (borderThickness / 2).toFloat())
when (shape) {
is OvalShape -> canvas.drawOval(rect, borderPaint)
is RoundRectShape -> canvas.drawRoundRect(rect, radius, radius, borderPaint)
else -> canvas.drawRect(rect, borderPaint)
}
}
override fun setAlpha(alpha: Int) {
textPaint.alpha = alpha
}
override fun setColorFilter(cf: ColorFilter?) {
textPaint.colorFilter = cf
}
override fun getOpacity(): Int {
return PixelFormat.TRANSLUCENT
}
override fun getIntrinsicWidth(): Int {
return width
}
override fun getIntrinsicHeight(): Int {
return height
}
class Builder : IConfigBuilder, IShapeBuilder, IBuilder {
var text: String? = null
var color: Int = 0
var borderThickness: Int = 0
var borderColor: Int = 0
var width: Int = 0
var height: Int = 0
var font: Typeface? = null
var shape: RectShape? = null
var textColor: Int = 0
var fontSize: Int = 0
var isBold: Boolean = false
var toUpperCase: Boolean = false
var radius: Float = 0.toFloat()
init {
text = ""
color = Color.GRAY
textColor = Color.WHITE
borderThickness = 0
borderColor = 0
width = -1
height = -1
shape = RectShape()
font = Typeface.create("sans-serif-light", Typeface.NORMAL)
fontSize = -1
isBold = false
toUpperCase = false
}
override fun width(width: Int): IConfigBuilder {
this.width = width
return this
}
override fun height(height: Int): IConfigBuilder {
this.height = height
return this
}
override fun textColor(color: Int): IConfigBuilder {
this.textColor = color
return this
}
override fun withBorder(thickness: Int): IConfigBuilder {
this.borderThickness = thickness
return this
}
override fun borderColor(color: Int): IConfigBuilder {
this.borderColor= borderColor
return this
}
override fun useFont(font: Typeface): IConfigBuilder {
this.font = font
return this
}
override fun fontSize(size: Int): IConfigBuilder {
this.fontSize = size
return this
}
override fun bold(): IConfigBuilder {
this.isBold = true
return this
}
override fun toUpperCase(): IConfigBuilder {
this.toUpperCase = true
return this
}
override fun beginConfig(): IConfigBuilder {
return this
}
override fun endConfig(): IShapeBuilder {
return this
}
override fun rect(): IBuilder {
this.shape = RectShape()
return this
}
override fun round(): IBuilder {
this.shape = OvalShape()
return this
}
override fun roundRect(radius: Int): IBuilder {
this.radius = radius.toFloat()
val radii = floatArrayOf(radius.toFloat(), radius.toFloat(), radius.toFloat(), radius.toFloat(), radius.toFloat(), radius.toFloat(), radius.toFloat(), radius.toFloat())
this.shape = RoundRectShape(radii, null, null)
return this
}
override fun buildRect(text: String, color: Int): TextDrawable {
rect()
return build(text, color)
}
override fun buildRoundRect(text: String, color: Int, radius: Int): TextDrawable {
roundRect(radius)
return build(text, color)
}
override fun buildRound(text: String, color: Int): TextDrawable {
round()
return build(text, color)
}
override fun build(text: String, color: Int): TextDrawable {
this.color = color
this.text = text
return TextDrawable(this)
}
}
interface IConfigBuilder {
fun width(width: Int): IConfigBuilder
fun height(height: Int): IConfigBuilder
fun textColor(color: Int): IConfigBuilder
fun withBorder(thickness: Int): IConfigBuilder
fun borderColor(color: Int): IConfigBuilder
fun useFont(font: Typeface): IConfigBuilder
fun fontSize(size: Int): IConfigBuilder
fun bold(): IConfigBuilder
fun toUpperCase(): IConfigBuilder
fun endConfig(): IShapeBuilder
}
interface IBuilder {
fun build(text: String, color: Int): TextDrawable
}
interface IShapeBuilder {
fun beginConfig(): IConfigBuilder
fun rect(): IBuilder
fun round(): IBuilder
fun roundRect(radius: Int): IBuilder
fun buildRect(text: String, color: Int): TextDrawable
fun buildRoundRect(text: String, color: Int, radius: Int): TextDrawable
fun buildRound(text: String, color: Int): TextDrawable
}
companion object {
private val SHADE_FACTOR = 0.9f
fun builder(): IShapeBuilder {
return Builder()
}
}
}
RecyclerViewClickListener.kt
interface RecyclerViewClickListener {
fun onNormalItemClicked(adapterPosition: Int)
fun onNumberedItemClick(adapterPosition: Int)
}
OverlapImageModel.kt
class OverlapImageModel {
var imageUrl: String? = null
}
row_image.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="@dimen/image_size"
android:layout_height="@dimen/image_size"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_gravity="center"
android:animateLayoutChanges="true">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/imageView"
app:civ_border_color="#ffffff"
app:civ_border_width="2dp"
android:layout_width="@dimen/image_size"
android:layout_height="@dimen/image_size"
android:layout_centerInParent="true"
tools:src="@mipmap/ic_launcher" />
</RelativeLayout>
关于java - 水平放置圆形图像以显示用户个人资料图片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52178656/
我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我试图在索引页中创建一个超链接,但它没有显示,也没有给出任何错误。这是我的index.html.erb代码。ListingarticlesTitleTextssss我检查了我的路线,我认为它们也没有问题。PrefixVerbURIPatternController#Actionwelcome_indexGET/welcome/index(.:format)welcome#indexarticlesGET/articles(.:format)articles#indexPOST/articles(.:format)articles#createnew_articleGET/article
我有一张背景图片,我想在其中添加一个文本框。我想弄清楚如何将标题放置在其顶部的正确位置。(我使用标题是因为我需要自动换行功能)。现在,我只能让文本显示在左上角,但我需要能够手动定位它的开始位置。require'RMagick'require'Pry'includeMagicktext="Loremipsumdolorsitamet"img=ImageList.new('template001.jpg')img 最佳答案 这是使用convert的ImageMagick命令行的答案。如果你想在Rmagick中使用这个方法,你必须自己移植
我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c
我是Rails的新手,所以请原谅简单的问题。我正在为一家公司创建一个网站。那家公司想在网站上展示它的客户。我想让客户自己管理这个。我正在为“客户”生成一个表格,我想要的三列是:公司名称、公司描述和Logo。对于名称,我使用的是name:string但不确定如何在脚本/生成脚手架终端命令中最好地创建描述列(因为我打算将其设置为文本区域)和图片。我怀疑描述(我想成为一个文本区域)应该仍然是描述:字符串,然后以实际形式进行调整。不确定如何处理图片字段。那么……说来话长:我在脚手架命令中输入什么来生成描述和图片列? 最佳答案 对于“文本”数
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www