Android中实现下拉刷新

article/2025/10/25 18:24:45

需求:项目中的消息列表界面要求实现类似sina微博的下拉刷新;

思路:一般的消息列表为ListView类型,将list加载到adapter中,再将adapter加载到ListView中,从而实现消息列表的展示。而下拉刷新要求给消息列表加一个头部,其中有图片(向上/向下箭头)和提示字样(下拉刷新/松开刷新),从而我们需要做的事情:1.需要做一个head.xm来实现头部的样式定义;2.需要自定义一个继承了ListView的MsgListView,在该类中将head加在MsgListView对象的头部;3.将原有的消息界面布局文件中的ListView改为cn.xd.microblogging.tools.MsgListView(包名.MsgListView);4.将原有的消息界面后台代码中创建的ListView对象改为MsgListView对象,注意消息界面Activity要继承ListActivity,并且实现其刷新监听。

说明:实现下拉刷新很简单,仅需要4个文件:MsgRcvListActivity.java(消息列表界面的后台文件,真正的刷新动作在这里完成,下拉刷新相关code下面列出),msgrcvlistactivity.xml(消息列表界面的前台文件,下拉刷新相关code下面列出),MsgListView.java(本文件拿来主义即可不用改,下拉刷新自定义的列表类,监听并执行下拉刷新、松开刷新、正在刷新、完成刷新等状态的改变,但真正的刷新动作不在这里完成,完整code下面列出),head.xml(本文件拿来主义即可不用改,下拉刷新的样式定义文件,包括向上、向下箭头,刷新状态提示等,完整code下面列出);

效果

代码

1.MsgRcvListActivity.java :

public class MsgRcvListActivity extends ListActivity {//注意:要继承ListActivity
…………//变量定义,略
MsgListView list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.msgrcvlistactivity);	
list=(MsgListView)findViewById(android.R.id.list);//继承ListActivity,id要写成android.R.id.list,否则报异常
…………//其他代码,略
//刷新监听,此处实现真正刷新
list.setonRefreshListener(new OnRefreshListener() {
public void onRefresh() {
new AsyncTask<Void, Void, Void>() {
protected Void doInBackground(Void... params) {
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void result) {
adapter.notifyDataSetChanged();
new MsgLoad().execute();//刷新监听中,真正执行刷新动作
list.onRefreshComplete();
}
}.execute(null);
}
});
list.setItemsCanFocus(false);            
list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
}
…………//其他代码,略
public class MsgLoad extends AsyncTask<Void, Void, List<MsgBean>> {
…………//其他代码,略
}
}

2.msgrcvlistactivity.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#000000">       
//将ListView改为包名.自定义的列表类名,MsgListView.java代码见后,此代码不需改通用,下拉刷新相关即此处,其他无关
<cn.xd.microblogging.tools.MsgListView
android:id="@android:id/list"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_weight="1.0"
android:drawSelectorOnTop="false"
android:scrollbars="vertical"
android:fadingEdgeLength="0dip" 
android:divider="@drawable/line"
android:dividerHeight="3.0dip"
android:cacheColorHint="#00000000" 
android:paddingBottom="40dp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/msg_list_load"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >      
<LinearLayout android:id="@android:id/empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >       
<include
android:id="@android:id/empty"
layout="@layout/empty_loading"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />      
</LinearLayout>
</LinearLayout>
</RelativeLayout>

3.MsgListView.java,拷进项目基本不需改:

package cn.xd.microblogging.tools;
import java.util.Date;
import cn.xd.microblogging.R;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ProgressBar;
import android.widget.TextView;
/**
* 
* 自定义MsgListView,继承了ListView,
* 但填充了listview的头部,即下拉刷新样式,并实现其功能
* @author yanbo
*
*/
public class MsgListView extends ListView implements OnScrollListener {
private final static int RELEASE_To_REFRESH = 0;
private final static int PULL_To_REFRESH = 1;
private final static int REFRESHING = 2;
private final static int DONE = 3;
private LayoutInflater inflater;
private LinearLayout headView; // 头部
private TextView tipsTextview;//下拉刷新
private TextView lastUpdatedTextView;//最新更新
private ImageView arrowImageView;//箭头
private ProgressBar progressBar;//刷新进度条
private RotateAnimation animation;//旋转特效 刷新中箭头翻转 向下变向上
private RotateAnimation reverseAnimation;
// 用于保证startY的值在一个完整的touch事件中只被记录一次
private boolean isRecored;
private int headContentWidth;//头部宽度
private int headContentHeight;//头部高度
private int startY;//高度起始位置,用来记录与头部距离
private int firstItemIndex;//列表中首行索引,用来记录其与头部距离
private int state;//下拉刷新中、松开刷新中、正在刷新中、完成刷新
private boolean isBack;
public OnRefreshListener refreshListener;//刷新监听
private final static String TAG = "abc";
public MsgListView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
inflater = LayoutInflater.from(context);
headView = (LinearLayout) inflater.inflate(R.layout.head, null);//listview拼接headview
arrowImageView = (ImageView) headView
.findViewById(R.id.head_arrowImageView);//headview中各view
arrowImageView.setMinimumWidth(50);
arrowImageView.setMinimumHeight(50);
progressBar = (ProgressBar) headView
.findViewById(R.id.head_progressBar);//headview中各view
tipsTextview = (TextView) headView.findViewById(R.id.head_tipsTextView);//headview中各view
lastUpdatedTextView = (TextView) headView
.findViewById(R.id.head_lastUpdatedTextView);//headview中各view
measureView(headView);
headContentHeight = headView.getMeasuredHeight();//头部高度
headContentWidth = headView.getMeasuredWidth();//头部宽度
headView.setPadding(0, -1 * headContentHeight, 0, 0);//setPadding(int left, int top, int right, int bottom) 
headView.invalidate();//Invalidate the whole view
Log.v("size", "width:" + headContentWidth + " height:"
+ headContentHeight);
addHeaderView(headView);//添加进headview
setOnScrollListener(this);//滚动监听
animation = new RotateAnimation(0, -180,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
animation.setInterpolator(new LinearInterpolator());
animation.setDuration(250);
animation.setFillAfter(true);//特效animation设置
reverseAnimation = new RotateAnimation(-180, 0,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
reverseAnimation.setInterpolator(new LinearInterpolator());
reverseAnimation.setDuration(250);
reverseAnimation.setFillAfter(true);//特效reverseAnimation设置
}
public void onScroll(AbsListView arg0, int firstVisiableItem, int arg2,//滚动事件
int arg3) {
firstItemIndex = firstVisiableItem;//得到首item索引
}
public void onScrollStateChanged(AbsListView arg0, int arg1) {
}
public boolean onTouchEvent(MotionEvent event) {//触摸事件
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN://手按下  对应下拉刷新状态
if (firstItemIndex == 0 && !isRecored) {//如果首item索引为0,且尚未记录startY,则在下拉时记录之,并执行isRecored = true;
startY = (int) event.getY();
isRecored = true;
Log.v(TAG, "在down时候记录当前位置‘");
}
break;
case MotionEvent.ACTION_UP://手松开  对应松开刷新状态
if (state != REFRESHING) {//手松开有4个状态:下拉刷新、松开刷新、正在刷新、完成刷新。如果当前不是正在刷新
if (state == DONE) {//如果当前是完成刷新,什么都不做
}
if (state == PULL_To_REFRESH) {//如果当前是下拉刷新,状态设为完成刷新(意即下拉刷新中就松开了,实际未完成刷新),执行changeHeaderViewByState()
state = DONE;
changeHeaderViewByState();
Log.v(TAG, "由下拉刷新状态,到done状态");
}
if (state == RELEASE_To_REFRESH) {//如果当前是松开刷新,状态设为正在刷新(意即松开刷新中松开手,才是真正地刷新),执行changeHeaderViewByState()
state = REFRESHING;
changeHeaderViewByState();
onRefresh();//真正刷新,所以执行onrefresh,执行后状态设为完成刷新
Log.v(TAG, "由松开刷新状态,到done状态");
}
}
isRecored = false;//手松开,则无论怎样,可以重新记录startY,因为只要手松开就认为一次刷新已完成
isBack = false;
break;
case MotionEvent.ACTION_MOVE://手拖动,拖动过程中不断地实时记录当前位置
int tempY = (int) event.getY();
if (!isRecored && firstItemIndex == 0) {//如果首item索引为0,且尚未记录startY,则在拖动时记录之,并执行isRecored = true;
Log.v(TAG, "在move时候记录下位置");
isRecored = true;
startY = tempY;
}
if (state != REFRESHING && isRecored) {//如果状态不是正在刷新,且已记录startY:tempY为拖动过程中一直在变的高度,startY为拖动起始高度
// 可以松手去刷新了
if (state == RELEASE_To_REFRESH) {//如果状态是松开刷新
// 往上推了,推到了屏幕足够掩盖head的程度,但是还没有推到全部掩盖的地步
if ((tempY - startY < headContentHeight)//如果实时高度大于起始高度,且两者之差小于头部高度,则状态设为下拉刷新
&& (tempY - startY) > 0) {
state = PULL_To_REFRESH;
changeHeaderViewByState();
Log.v(TAG, "由松开刷新状态转变到下拉刷新状态");
}
// 一下子推到顶了
else if (tempY - startY <= 0) {//如果实时高度小于等于起始高度了,则说明到顶了,状态设为完成刷新
state = DONE;
changeHeaderViewByState();
Log.v(TAG, "由松开刷新状态转变到done状态");
}
// 往下拉了,或者还没有上推到屏幕顶部掩盖head的地步
else {//如果当前拖动过程中既没有到下拉刷新的地步,也没有到完成刷新(到顶)的地步,则保持松开刷新状态
// 不用进行特别的操作,只用更新paddingTop的值就行了
}
}
// 还没有到达显示松开刷新的时候,DONE或者是PULL_To_REFRESH状态
if (state == PULL_To_REFRESH) {//如果状态是下拉刷新
// 下拉到可以进入RELEASE_TO_REFRESH的状态
if (tempY - startY >= headContentHeight) {//如果实时高度与起始高度之差大于等于头部高度,则状态设为松开刷新
state = RELEASE_To_REFRESH;
isBack = true;
changeHeaderViewByState();
Log.v(TAG, "由done或者下拉刷新状态转变到松开刷新");
}
// 上推到顶了
else if (tempY - startY <= 0) {//如果实时高度小于等于起始高度了,则说明到顶了,状态设为完成刷新
state = DONE;
changeHeaderViewByState();
Log.v(TAG, "由DOne或者下拉刷新状态转变到done状态");
}
}
// done状态下
if (state == DONE) {//如果状态是完成刷新
if (tempY - startY > 0) {//如果实时高度大于起始高度了,则状态设为下拉刷新
state = PULL_To_REFRESH;
changeHeaderViewByState();
}
}
// 更新headView的size
if (state == PULL_To_REFRESH) {//如果状态是下拉刷新,更新headview的size           ?
headView.setPadding(0, -1 * headContentHeight
+ (tempY - startY), 0, 0);
headView.invalidate();
}
// 更新headView的paddingTop
if (state == RELEASE_To_REFRESH) {//如果状态是松开刷新,更新 headview的paddingtop      ?
headView.setPadding(0, tempY - startY - headContentHeight,
0, 0);
headView.invalidate();
}
}
break;
}
return super.onTouchEvent(event);
}
// 当状态改变时候,调用该方法,以更新界面
private void changeHeaderViewByState() {
switch (state) {
case RELEASE_To_REFRESH:
arrowImageView.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);
tipsTextview.setVisibility(View.VISIBLE);
lastUpdatedTextView.setVisibility(View.VISIBLE);
arrowImageView.clearAnimation();
arrowImageView.startAnimation(animation);
tipsTextview.setText("松开刷新");
Log.v(TAG, "当前状态,松开刷新");
break;
case PULL_To_REFRESH:
progressBar.setVisibility(View.GONE);
tipsTextview.setVisibility(View.VISIBLE);
lastUpdatedTextView.setVisibility(View.VISIBLE);
arrowImageView.clearAnimation();
arrowImageView.setVisibility(View.VISIBLE);
// 是由RELEASE_To_REFRESH状态转变来的
if (isBack) {
isBack = false;
arrowImageView.clearAnimation();
arrowImageView.startAnimation(reverseAnimation);
tipsTextview.setText("下拉刷新");
} else {
tipsTextview.setText("下拉刷新");
}
Log.v(TAG, "当前状态,下拉刷新");
break;
case REFRESHING:
headView.setPadding(0, 0, 0, 0);
headView.invalidate();
progressBar.setVisibility(View.VISIBLE);
arrowImageView.clearAnimation();
arrowImageView.setVisibility(View.GONE);
tipsTextview.setText("正在刷新...");
lastUpdatedTextView.setVisibility(View.VISIBLE);
Log.v(TAG, "当前状态,正在刷新...");
break;
case DONE:
headView.setPadding(0, -1 * headContentHeight, 0, 0);
headView.invalidate();
progressBar.setVisibility(View.GONE);
arrowImageView.clearAnimation();
arrowImageView
.setImageResource(R.drawable.ic_pulltorefresh_arrow);
tipsTextview.setText("下拉刷新");
lastUpdatedTextView.setVisibility(View.VISIBLE);
Log.v(TAG, "当前状态,done");
break;
}
}
public void setonRefreshListener(OnRefreshListener refreshListener) {
this.refreshListener = refreshListener;
}
public interface OnRefreshListener {
public void onRefresh();
}
public void onRefreshComplete() {
state = DONE;
lastUpdatedTextView.setText("最近更新:" + new Date().toLocaleString());//刷新完成时,头部提醒的刷新日期
changeHeaderViewByState();
}
private void onRefresh() {
if (refreshListener != null) {
refreshListener.onRefresh();
}
}
//此方法直接照搬自网络上的一个下拉刷新的demo,此处是“估计”headView的width以及height
private void measureView(View child) {
ViewGroup.LayoutParams p = child.getLayoutParams();
if (p == null) {
p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);
int lpHeight = p.height;
int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,
MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0,
MeasureSpec.UNSPECIFIED);
}
child.measure(childWidthSpec, childHeightSpec);
}
}

4.head.xml,拷进项目基本不需改:

<?xml version="1.0" encoding="utf-8"?>
<!-- ListView的头部 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/head_rootLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<!-- 内容 -->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/head_contentLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="30dp" >
<!-- 箭头图像、进度条 -->
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true" >
<!-- 箭头 -->
<ImageView
android:id="@+id/head_arrowImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_pulltorefresh_arrow" 
android:contentDescription="@string/app_name"/>
<!-- 进度条 -->
<ProgressBar
android:id="@+id/head_progressBar"
style="?android:attr/progressBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
</FrameLayout>
<!-- 提示、最近更新 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:gravity="center_horizontal"
android:orientation="vertical" >
<!-- 提示 -->
<TextView
android:id="@+id/head_tipsTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/pulltorefresh"
android:textColor="#ffffff"
android:textSize="20sp" />
<!-- 最近更新 -->
<TextView
android:id="@+id/head_lastUpdatedTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/lastupdate"
android:textColor="#cc6600"
android:textSize="10sp" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>

 殊途同归,扩展借鉴其他下拉刷新方式:

http://blog.csdn.net/nono_love_lilith/article/details/7100845
http://blog.csdn.net/nono_love_lilith/article/details/7202651

 

 

 


http://chatgpt.dhexx.cn/article/hhlyqeWY.shtml

相关文章

微信小程序下拉刷新

一、如何设置微信小程序所有页面都可以下拉刷新呢&#xff1f; 1、在app.json的"window"中进行配置 &#xff08;1&#xff09;把"backgroundTextStyle":“light"改为"backgroundTextStyle”:“dark” &#xff08;2&#xff09;添加"enab…

下拉刷新上拉加载

目录 原理实现效果 原理 想必使用过微信开发工具的应该都接触过上拉加载下拉刷新配置。 原理呢就是通过根据当前刚开始触碰的屏幕垂直y轴距离和滑动时所触碰垂直y轴距离&#xff0c;从而来判断是上拉&#xff0c;下拉。 实现 使用的vue2 封装的组件&#xff0c;js大致思路是…

Android下拉刷新完全解析,教你如何一分钟实现下拉刷新功能

转载请注明出处&#xff1a;http://blog.csdn.net/guolin_blog/article/details/9255575 最近项目中需要用到ListView下拉刷新的功能&#xff0c;一开始想图省事&#xff0c;在网上直接找一个现成的&#xff0c;可是尝试了网上多个版本的下拉刷新之后发现效果都不怎么理想。有些…

【Demo】教你实现下拉刷新

前言 第三方库很常见&#xff0c;我们开发需求的时候经常会用到下拉刷新组件&#xff0c;如果要我们自己实现下拉刷新该如何实现尼&#xff1f; 效果 实现原理 1、监听 touchstart事件记录初始startY 2、监听 touchmove事件 e.touches[0].pageY - startY得到 deltaY&#xf…

如何实现上拉加载,下拉刷新

答&#xff1a;下拉刷新和上拉加载这两种交互⽅式通常出现在移动端中 本质上等同于PC⽹⻚中的分⻚&#xff0c;只是交互形式不同 开源社区也有很多优秀的解决⽅案&#xff0c;如 iscroll 、 better-scroll 、 pulltorefresh.js 库等等 这些第三⽅库使⽤起来⾮常便捷 我们通…

jira使用教程管理项目

添加工作流 1.点击项目设置 2.点击工作流&#xff0c;然后点击切换方案 3.进入切换方案界面之后&#xff0c;点击工作流&#xff0c;然后点击添加工作流 4.输入工作流名称&#xff0c;点击添加 5.编辑工作流 可以导出工作流供别人使用 编辑之前添加的工作流 提交bug

今日记录:JIRA使用指南

JIRA流程与使用指南 学习总结&#xff1a; 什么是JIRA&#xff1f;为什么要用任务管理工具&#xff1f;JIRA基础流程 ① 什么是JIRA&#xff1f; JIRA是一个项目与事务管理工具&#xff0c;被广泛应用于缺陷跟踪、客户服务、需求收集、流程审批、任务跟踪和敏捷管理等工作领…

JIRA-使用教程_概念

博客概要 JIRA是一个非常强大的项目与事务跟踪工具&#xff0c;博主在具体工作使用中对它爱不释手 &#xff0c;发现它功能全面、配置灵活、扩展丰富…反正优点一大堆&#xff01;好东西嘛就要拿出来&#xff0c;大家一起分享~本博文先简单介绍JIRA相关的基本信息。 文章目录 博…

Confluence+Jira使用

Jira过滤器的使用方式&#xff1a; project MCU AND issuetype 测试用例 AND component GPIO ORDER BY summary ASC实例&#xff1a;

jira使用教程 一(从官方文档理解)

JIRA官方说明 JIRA使用教程 blog QA: jira 如何关联到Gerrit Reviews JIRA Concepts - Issues Aim JIRA tracks issues, which can be bugs, feature requests, or any other tasks you want to track. JIRA可以跟踪问题&#xff0c;可以是bug、特性请求或任何其他你想跟踪…

JIRA-使用教程_问题单-新建

博客概要 简单分享新增并查看一个问题单的步骤~ 文章目录 博客概要《JIRA-使用教程》_总目录问题单-新建1.进入项目2.新建唤起3.填写新建弹窗4.查看问题 总结 《JIRA-使用教程》_总目录 文章超链接&#xff1a;https://blog.csdn.net/qq_41386332/article/details/108865809 …

项目管理工具——Jira使用和配置

摘要 链接&#xff1a;https://pan.baidu.com/s/1_PgOuOWsS1lnHIIyI0y4pA 提取码&#xff1a;v0dy 本博文将介绍在软件开发中的常用的软件管理工具。Jira是Atlassian公司出品的一款事务管理软件&#xff08;缺陷管理类的软件&#xff09;。无论是“需求”&#xff0c;还是“…

命令进入mysql创建jira_JIRA使用教程:连接数据库—MySQL_MySQL

本文主要介绍如何连接JIRA到mysql数据库。 首先 查看MySQL的版本是否支持&#xff0c;查阅 支持的平台 。 如果是转移JIRA到另一台服务器&#xff0c;先导出数据为XML备份&#xff0c;然后将旧数据库中的数据传输到新的数据库。 如果你打算用同一个MySQL服务器安装Confluence和…

jira oracle安装,JIRA使用教程:连接数据库—Oracle

本文主要介绍连接JIRA到Oracle数据库。 首先 检查Oracle的版本是否支持&#xff0c;详见支持的平台。 如果是转移JIRA到另一台服务器&#xff0c;先导出数据为XML备份&#xff0c;然后将旧数据库中的数据传输到新的数据库。 在开始前关闭JIRA&#xff0c;除非你正在运行Setup W…

命令进入mysql创建jira_JIRA使用教程:连接数据库―MySQL

本文主要介绍如何连接JIRA到mysql数据库。 首先 查看MySQL的版本是否支持&#xff0c;查阅 支持的平台 。 如果是转移JIRA到另一台服务器&#xff0c;先导出数据为XML备份&#xff0c;然后将旧数据库中的数据传输到新的数据库。 如果你打算用同一个MySQL服务器安装Confluence和…

Jira使用浅谈篇一

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

jira软件 linux 安装,JIRA使用教程:在Linux上安装JIRA

本指南主要介绍如何使用“Linux Installer”在Linux上安装一个新的JIRA。如果要升级请参阅JIRA升级指南。 申请试用请咨询在线客服。 注意&#xff1a;一些反病毒或其他互联网安全工具可能会干扰JIRA的安装过程&#xff0c;并阻止安装过程成功完成。为了避免遇到这样的情况&…

jira的详细使用教程

jira的详细使用教程,1,Jira- 是一款缺陷管理软件工具,用其进行缺陷的管理和跟踪。(是B/S架构的软件) 2,主要涉及的角色: 3,具体工作流 添加工作流 1.点击项目设置 2.点击工作流,然后点击切换方案 3.进入切换

命令进入mysql创建jira_JIRA使用教程

连接数据库—MySQL 本文主要介绍如何连接JIRA到MySQL数据库。 相关资料推荐&#xff1a; 首先查看MySQL的版本是否支持&#xff0c;查阅支持的平台。 如果是转移JIRA到另一台服务器&#xff0c;先导出数据为XML备份&#xff0c;然后将旧数据库中的数据传输到新的数据库。 如果你…

Jira使用教程-不古出品

Jira使用教程-不古出品 Jira 简要概述关于 Jira关键术语事务项目板工作流敏捷 Jira 入门教程&#xff1a;6 个基本步骤第 1 步 – 创建项目第 2 步 – 选择模板项目类型 第 3 步 - 设置列第 4 步 – 创建事务第 5 步 – 邀请团队第 6 步 - 推动工作进展 Jira 最佳实践Jira 项目…